diff --git a/libs/vtextedit b/libs/vtextedit index 34ad7467..8bcd2f04 160000 --- a/libs/vtextedit +++ b/libs/vtextedit @@ -1 +1 @@ -Subproject commit 34ad7467eb42b5d1d228228d875a7675814f222b +Subproject commit 8bcd2f0416df45409bb3b97c330adea7e3e3295b diff --git a/src/core/markdowneditorconfig.cpp b/src/core/markdowneditorconfig.cpp index 896dd952..827d6719 100644 --- a/src/core/markdowneditorconfig.cpp +++ b/src/core/markdowneditorconfig.cpp @@ -48,7 +48,7 @@ void MarkdownEditorConfig::init(const QJsonObject &p_app, const QJsonObject &p_u m_sectionNumberStyle = stringToSectionNumberStyle(READSTR(QStringLiteral("section_number_style"))); m_constrainImageWidthEnabled = READBOOL(QStringLiteral("constrain_image_width")); - m_constrainInPlacePreviewWidthEnabled = READBOOL(QStringLiteral("constrain_inplace_preview_width")); + m_constrainInplacePreviewWidthEnabled = READBOOL(QStringLiteral("constrain_inplace_preview_width")); m_zoomFactorInReadMode = READREAL(QStringLiteral("zoom_factor_in_read_mode")); m_fetchImagesInParseAndPaste = READBOOL(QStringLiteral("fetch_images_in_parse_and_paste")); @@ -64,6 +64,14 @@ void MarkdownEditorConfig::init(const QJsonObject &p_app, const QJsonObject &p_u m_spellCheckEnabled = READBOOL(QStringLiteral("spell_check")); m_editorOverriddenFontFamily = READSTR(QStringLiteral("editor_overridden_font_family")); + + { + m_inplacePreviewSources = InplacePreviewSource::NoInplacePreview; + auto srcs = READSTR(QStringLiteral("inplace_preview_sources")).split(QLatin1Char(';')); + for (const auto &src : srcs) { + m_inplacePreviewSources |= stringToInplacePreviewSource(src); + } + } } QJsonObject MarkdownEditorConfig::toJson() const @@ -85,7 +93,7 @@ QJsonObject MarkdownEditorConfig::toJson() const obj[QStringLiteral("section_number_style")] = sectionNumberStyleToString(m_sectionNumberStyle); obj[QStringLiteral("constrain_image_width")] = m_constrainImageWidthEnabled; - obj[QStringLiteral("constrain_inplace_preview_width")] = m_constrainInPlacePreviewWidthEnabled; + obj[QStringLiteral("constrain_inplace_preview_width")] = m_constrainInplacePreviewWidthEnabled; obj[QStringLiteral("zoom_factor_in_read_mode")] = m_zoomFactorInReadMode; obj[QStringLiteral("fetch_images_in_parse_and_paste")] = m_fetchImagesInParseAndPaste; obj[QStringLiteral("protect_from_xss")] = m_protectFromXss; @@ -97,6 +105,21 @@ QJsonObject MarkdownEditorConfig::toJson() const obj[QStringLiteral("smart_table_interval")] = m_smartTableInterval; obj[QStringLiteral("spell_check")] = m_spellCheckEnabled; obj[QStringLiteral("editor_overridden_font_family")] = m_editorOverriddenFontFamily; + + { + QStringList srcs; + if (m_inplacePreviewSources & InplacePreviewSource::ImageLink) { + srcs << inplacePreviewSourceToString(InplacePreviewSource::ImageLink); + } + if (m_inplacePreviewSources & InplacePreviewSource::CodeBlock) { + srcs << inplacePreviewSourceToString(InplacePreviewSource::CodeBlock); + } + if (m_inplacePreviewSources & InplacePreviewSource::Math) { + srcs << inplacePreviewSourceToString(InplacePreviewSource::Math); + } + obj[QStringLiteral("inplace_preview_sources")] = srcs.join(QLatin1Char(';')); + } + return obj; } @@ -257,14 +280,14 @@ void MarkdownEditorConfig::setConstrainImageWidthEnabled(bool p_enabled) updateConfig(m_constrainImageWidthEnabled, p_enabled, this); } -bool MarkdownEditorConfig::getConstrainInPlacePreviewWidthEnabled() const +bool MarkdownEditorConfig::getConstrainInplacePreviewWidthEnabled() const { - return m_constrainInPlacePreviewWidthEnabled; + return m_constrainInplacePreviewWidthEnabled; } -void MarkdownEditorConfig::setConstrainInPlacePreviewWidthEnabled(bool p_enabled) +void MarkdownEditorConfig::setConstrainInplacePreviewWidthEnabled(bool p_enabled) { - updateConfig(m_constrainInPlacePreviewWidthEnabled, p_enabled, this); + updateConfig(m_constrainInplacePreviewWidthEnabled, p_enabled, this); } qreal MarkdownEditorConfig::getZoomFactorInReadMode() const @@ -379,6 +402,37 @@ MarkdownEditorConfig::SectionNumberStyle MarkdownEditorConfig::stringToSectionNu } } +QString MarkdownEditorConfig::inplacePreviewSourceToString(InplacePreviewSource p_src) const +{ + switch (p_src) { + case InplacePreviewSource::ImageLink: + return QStringLiteral("imagelink"); + + case InplacePreviewSource::CodeBlock: + return QStringLiteral("codeblock"); + + case InplacePreviewSource::Math: + return QStringLiteral("math"); + + default: + return ""; + } +} + +MarkdownEditorConfig::InplacePreviewSource MarkdownEditorConfig::stringToInplacePreviewSource(const QString &p_str) const +{ + auto src = p_str.toLower(); + if (src == QStringLiteral("imagelink")) { + return InplacePreviewSource::ImageLink; + } else if (src == QStringLiteral("codeblock")) { + return InplacePreviewSource::CodeBlock; + } else if (src == QStringLiteral("math")) { + return InplacePreviewSource::Math; + } else { + return InplacePreviewSource::NoInplacePreview; + } +} + MarkdownEditorConfig::SectionNumberMode MarkdownEditorConfig::getSectionNumberMode() const { return m_sectionNumberMode; @@ -443,3 +497,13 @@ void MarkdownEditorConfig::setEditorOverriddenFontFamily(const QString &p_family { updateConfig(m_editorOverriddenFontFamily, p_family, this); } + +MarkdownEditorConfig::InplacePreviewSources MarkdownEditorConfig::getInplacePreviewSources() const +{ + return m_inplacePreviewSources; +} + +void MarkdownEditorConfig::setInplacePreviewSources(InplacePreviewSources p_src) +{ + updateConfig(m_inplacePreviewSources, p_src, this); +} diff --git a/src/core/markdowneditorconfig.h b/src/core/markdowneditorconfig.h index 139ce9bc..d9916264 100644 --- a/src/core/markdowneditorconfig.h +++ b/src/core/markdowneditorconfig.h @@ -30,6 +30,15 @@ namespace vnotex DigDotDig }; + enum InplacePreviewSource + { + NoInplacePreview = 0, + ImageLink = 0x1, + CodeBlock = 0x2, + Math = 0x4 + }; + Q_DECLARE_FLAGS(InplacePreviewSources, InplacePreviewSource); + MarkdownEditorConfig(ConfigMgr *p_mgr, IConfig *p_topConfig, const QSharedPointer &p_textEditorConfig); @@ -81,8 +90,8 @@ namespace vnotex bool getConstrainImageWidthEnabled() const; void setConstrainImageWidthEnabled(bool p_enabled); - bool getConstrainInPlacePreviewWidthEnabled() const; - void setConstrainInPlacePreviewWidthEnabled(bool p_enabled); + bool getConstrainInplacePreviewWidthEnabled() const; + void setConstrainInplacePreviewWidthEnabled(bool p_enabled); qreal getZoomFactorInReadMode() const; void setZoomFactorInReadMode(qreal p_factor); @@ -115,6 +124,9 @@ namespace vnotex const QString &getEditorOverriddenFontFamily() const; void setEditorOverriddenFontFamily(const QString &p_family); + InplacePreviewSources getInplacePreviewSources() const; + void setInplacePreviewSources(InplacePreviewSources p_src); + private: QString sectionNumberModeToString(SectionNumberMode p_mode) const; SectionNumberMode stringToSectionNumberMode(const QString &p_str) const; @@ -128,6 +140,9 @@ namespace vnotex void loadExportResource(const QJsonObject &p_app, const QJsonObject &p_user); QJsonObject saveExportResource() const; + QString inplacePreviewSourceToString(InplacePreviewSource p_src) const; + InplacePreviewSource stringToInplacePreviewSource(const QString &p_str) const; + QSharedPointer m_textEditorConfig; WebResource m_viewerResource; @@ -171,7 +186,7 @@ namespace vnotex bool m_constrainImageWidthEnabled = true; // Whether enable in-place preview width constraint. - bool m_constrainInPlacePreviewWidthEnabled = false; + bool m_constrainInplacePreviewWidthEnabled = false; qreal m_zoomFactorInReadMode = 1.0; @@ -203,7 +218,11 @@ namespace vnotex // Font family to override the editor's theme. QString m_editorOverriddenFontFamily; + + InplacePreviewSources m_inplacePreviewSources = InplacePreviewSource::NoInplacePreview; }; } +Q_DECLARE_OPERATORS_FOR_FLAGS(vnotex::MarkdownEditorConfig::InplacePreviewSources) + #endif // MARKDOWNEDITORCONFIG_H diff --git a/src/data/core/vnotex.json b/src/data/core/vnotex.json index c3de49cf..65a4e2dd 100644 --- a/src/data/core/vnotex.json +++ b/src/data/core/vnotex.json @@ -330,7 +330,10 @@ "//comment" : "Time interval (milliseconds) to do smart table formatting", "smart_table_interval" : 1000, "spell_check" : true, - "editor_overridden_font_family" : "" + "editor_overridden_font_family" : "", + "//comment" : "Sources to enable inplace preview, separated by ;", + "//comment" : "imagelink/codeblock/math", + "inplace_preview_sources" : "imagelink;codeblock;math" } }, "widget" : { diff --git a/src/widgets/dialogs/settings/markdowneditorpage.cpp b/src/widgets/dialogs/settings/markdowneditorpage.cpp index 9fe654bd..d6f773a0 100644 --- a/src/widgets/dialogs/settings/markdowneditorpage.cpp +++ b/src/widgets/dialogs/settings/markdowneditorpage.cpp @@ -69,7 +69,14 @@ void MarkdownEditorPage::loadInternal() m_zoomFactorSpinBox->setValue(markdownConfig.getZoomFactorInReadMode()); - m_constrainInPlacePreviewWidthCheckBox->setChecked(markdownConfig.getConstrainInPlacePreviewWidthEnabled()); + m_constrainInplacePreviewWidthCheckBox->setChecked(markdownConfig.getConstrainInplacePreviewWidthEnabled()); + + { + auto srcs = markdownConfig.getInplacePreviewSources(); + m_inplacePreviewSourceImageLinkCheckBox->setChecked(srcs & MarkdownEditorConfig::InplacePreviewSource::ImageLink); + m_inplacePreviewSourceCodeBlockCheckBox->setChecked(srcs & MarkdownEditorConfig::InplacePreviewSource::CodeBlock); + m_inplacePreviewSourceMathCheckBox->setChecked(srcs & MarkdownEditorConfig::InplacePreviewSource::Math); + } m_fetchImagesToLocalCheckBox->setChecked(markdownConfig.getFetchImagesInParseAndPaste()); @@ -134,7 +141,22 @@ void MarkdownEditorPage::saveInternal() markdownConfig.setZoomFactorInReadMode(m_zoomFactorSpinBox->value()); - markdownConfig.setConstrainInPlacePreviewWidthEnabled(m_constrainInPlacePreviewWidthCheckBox->isChecked()); + markdownConfig.setConstrainInplacePreviewWidthEnabled(m_constrainInplacePreviewWidthCheckBox->isChecked()); + + { + MarkdownEditorConfig::InplacePreviewSources srcs = MarkdownEditorConfig::InplacePreviewSource::NoInplacePreview; + if (m_inplacePreviewSourceImageLinkCheckBox->isChecked()) { + srcs |= MarkdownEditorConfig::InplacePreviewSource::ImageLink; + } + if (m_inplacePreviewSourceCodeBlockCheckBox->isChecked()) { + srcs |= MarkdownEditorConfig::InplacePreviewSource::CodeBlock; + } + if (m_inplacePreviewSourceMathCheckBox->isChecked()) { + srcs |= MarkdownEditorConfig::InplacePreviewSource::Math; + } + + markdownConfig.setInplacePreviewSources(srcs); + } markdownConfig.setFetchImagesInParseAndPaste(m_fetchImagesToLocalCheckBox->isChecked()); @@ -260,11 +282,31 @@ QGroupBox *MarkdownEditorPage::setupEditGroup() { const QString label(tr("Constrain in-place preview width")); - m_constrainInPlacePreviewWidthCheckBox = WidgetsFactory::createCheckBox(label, box); - m_constrainInPlacePreviewWidthCheckBox->setToolTip(tr("Constrain in-place preview width to the window")); - layout->addRow(m_constrainInPlacePreviewWidthCheckBox); - addSearchItem(label, m_constrainInPlacePreviewWidthCheckBox->toolTip(), m_constrainInPlacePreviewWidthCheckBox); - connect(m_constrainInPlacePreviewWidthCheckBox, &QCheckBox::stateChanged, + m_constrainInplacePreviewWidthCheckBox = WidgetsFactory::createCheckBox(label, box); + m_constrainInplacePreviewWidthCheckBox->setToolTip(tr("Constrain in-place preview width to the window")); + layout->addRow(m_constrainInplacePreviewWidthCheckBox); + addSearchItem(label, m_constrainInplacePreviewWidthCheckBox->toolTip(), m_constrainInplacePreviewWidthCheckBox); + connect(m_constrainInplacePreviewWidthCheckBox, &QCheckBox::stateChanged, + this, &MarkdownEditorPage::pageIsChanged); + } + + { + auto srcLayout = new QVBoxLayout(); + layout->addRow(tr("In-place preview sources:"), srcLayout); + + m_inplacePreviewSourceImageLinkCheckBox = WidgetsFactory::createCheckBox(tr("Image link"), box); + srcLayout->addWidget(m_inplacePreviewSourceImageLinkCheckBox); + connect(m_inplacePreviewSourceImageLinkCheckBox, &QCheckBox::stateChanged, + this, &MarkdownEditorPage::pageIsChanged); + + m_inplacePreviewSourceCodeBlockCheckBox = WidgetsFactory::createCheckBox(tr("Code block"), box); + srcLayout->addWidget(m_inplacePreviewSourceCodeBlockCheckBox); + connect(m_inplacePreviewSourceCodeBlockCheckBox, &QCheckBox::stateChanged, + this, &MarkdownEditorPage::pageIsChanged); + + m_inplacePreviewSourceMathCheckBox = WidgetsFactory::createCheckBox(tr("Math"), box); + srcLayout->addWidget(m_inplacePreviewSourceMathCheckBox); + connect(m_inplacePreviewSourceMathCheckBox, &QCheckBox::stateChanged, this, &MarkdownEditorPage::pageIsChanged); } diff --git a/src/widgets/dialogs/settings/markdowneditorpage.h b/src/widgets/dialogs/settings/markdowneditorpage.h index 6fabb0e3..2f660ed3 100644 --- a/src/widgets/dialogs/settings/markdowneditorpage.h +++ b/src/widgets/dialogs/settings/markdowneditorpage.h @@ -40,7 +40,13 @@ namespace vnotex QCheckBox *m_constrainImageWidthCheckBox = nullptr; - QCheckBox *m_constrainInPlacePreviewWidthCheckBox = nullptr; + QCheckBox *m_constrainInplacePreviewWidthCheckBox = nullptr; + + QCheckBox *m_inplacePreviewSourceImageLinkCheckBox = nullptr; + + QCheckBox *m_inplacePreviewSourceCodeBlockCheckBox = nullptr; + + QCheckBox *m_inplacePreviewSourceMathCheckBox = nullptr; QCheckBox *m_fetchImagesToLocalCheckBox = nullptr; diff --git a/src/widgets/editors/previewhelper.cpp b/src/widgets/editors/previewhelper.cpp index 1ac91b23..2b4a3074 100644 --- a/src/widgets/editors/previewhelper.cpp +++ b/src/widgets/editors/previewhelper.cpp @@ -142,7 +142,7 @@ void PreviewHelper::codeBlocksUpdated(vte::TimeStamp p_timeStamp, const QVector &p_codeBlocks) { Q_UNUSED(p_timeStamp); - if (!m_inplacePreviewEnabled) { + if (!m_inplacePreviewCodeBlocksEnabled) { return; } @@ -180,7 +180,7 @@ void PreviewHelper::handleCodeBlocksUpdate() m_tabStopWidth); } - if (m_inplacePreviewEnabled && needPreview.first && !cacheHit) { + if (m_inplacePreviewCodeBlocksEnabled && needPreview.first && !cacheHit) { m_codeBlocksData[blockPreviewIdx].m_text = cb.m_text; needPreviewBlocks.push_back(blockPreviewIdx); } @@ -354,7 +354,7 @@ void PreviewHelper::setMarkdownEditor(MarkdownEditor *p_editor) void PreviewHelper::mathBlocksUpdated(const QVector &p_mathBlocks) { - if (!m_inplacePreviewEnabled || !isInplacePreviewSourceEnabled(SourceFlag::Math)) { + if (!m_inplacePreviewMathBlocksEnabled || !isInplacePreviewSourceEnabled(SourceFlag::Math)) { return; } @@ -528,3 +528,18 @@ bool PreviewHelper::needForcedBackground(const QString &p_lang) const return false; } + +void PreviewHelper::setInplacePreviewSources(SourceFlags p_srcs) +{ + m_inplacePreviewSources = p_srcs; +} + +void PreviewHelper::setInplacePreviewCodeBlocksEnabled(bool p_enabled) +{ + m_inplacePreviewCodeBlocksEnabled = p_enabled; +} + +void PreviewHelper::setInplacePreviewMathBlocksEnabled(bool p_enabled) +{ + m_inplacePreviewMathBlocksEnabled = p_enabled; +} diff --git a/src/widgets/editors/previewhelper.h b/src/widgets/editors/previewhelper.h index bfa91bec..76f4ffc5 100644 --- a/src/widgets/editors/previewhelper.h +++ b/src/widgets/editors/previewhelper.h @@ -47,6 +47,12 @@ namespace vnotex void setWebGraphvizEnabled(bool p_enabled); + void setInplacePreviewSources(SourceFlags p_srcs); + + void setInplacePreviewCodeBlocksEnabled(bool p_enabled); + + void setInplacePreviewMathBlocksEnabled(bool p_enabled); + public slots: void codeBlocksUpdated(vte::TimeStamp p_timeStamp, const QVector &p_codeBlocks); @@ -201,7 +207,9 @@ namespace vnotex // Need to init it in the constructor. SourceFlags m_inplacePreviewSources; - bool m_inplacePreviewEnabled = true; + bool m_inplacePreviewCodeBlocksEnabled = true; + + bool m_inplacePreviewMathBlocksEnabled = true; TimeStamp m_codeBlockTimeStamp = 0; diff --git a/src/widgets/markdownviewwindow.cpp b/src/widgets/markdownviewwindow.cpp index bc53a2b9..0d77413e 100644 --- a/src/widgets/markdownviewwindow.cpp +++ b/src/widgets/markdownviewwindow.cpp @@ -179,8 +179,7 @@ void MarkdownViewWindow::handleEditorConfigChange() if (markdownEditorConfig.revision() != m_markdownEditorConfigRevision) { m_markdownEditorConfigRevision = markdownEditorConfig.revision(); - m_previewHelper->setWebPlantUmlEnabled(markdownEditorConfig.getWebPlantUml()); - m_previewHelper->setWebGraphvizEnabled(markdownEditorConfig.getWebGraphviz()); + updatePreviewHelperFromConfig(markdownEditorConfig); HtmlTemplateHelper::updateMarkdownViewerTemplate(markdownEditorConfig); @@ -792,7 +791,23 @@ QSharedPointer MarkdownViewWindow::createMarkdownEdit auto editorConfig = QSharedPointer::create(textEditorConfig); editorConfig->overrideTextFontFamily(p_config.getEditorOverriddenFontFamily()); - editorConfig->m_constrainInPlacePreviewWidthEnabled = p_config.getConstrainInPlacePreviewWidthEnabled(); + editorConfig->m_constrainInplacePreviewWidthEnabled = p_config.getConstrainInplacePreviewWidthEnabled(); + + { + auto srcs = p_config.getInplacePreviewSources(); + vte::MarkdownEditorConfig::InplacePreviewSources editorSrcs = vte::MarkdownEditorConfig::NoInplacePreview; + if (srcs & MarkdownEditorConfig::InplacePreviewSource::ImageLink) { + editorSrcs |= vte::MarkdownEditorConfig::ImageLink; + } + if (srcs & MarkdownEditorConfig::InplacePreviewSource::CodeBlock) { + editorSrcs |= vte::MarkdownEditorConfig::CodeBlock; + } + if (srcs & MarkdownEditorConfig::InplacePreviewSource::Math) { + editorSrcs |= vte::MarkdownEditorConfig::Math; + } + editorConfig->m_inplacePreviewSources = editorSrcs; + } + return editorConfig; } @@ -967,8 +982,7 @@ void MarkdownViewWindow::setupPreviewHelper() m_previewHelper = new PreviewHelper(nullptr, this); const auto &markdownEditorConfig = ConfigMgr::getInst().getEditorConfig().getMarkdownEditorConfig(); - m_previewHelper->setWebPlantUmlEnabled(markdownEditorConfig.getWebPlantUml()); - m_previewHelper->setWebGraphvizEnabled(markdownEditorConfig.getWebGraphviz()); + updatePreviewHelperFromConfig(markdownEditorConfig); PlantUmlHelper::getInst().init(markdownEditorConfig.getPlantUmlJar(), markdownEditorConfig.getGraphvizExe(), @@ -976,6 +990,16 @@ void MarkdownViewWindow::setupPreviewHelper() GraphvizHelper::getInst().init(markdownEditorConfig.getGraphvizExe()); } +void MarkdownViewWindow::updatePreviewHelperFromConfig(const MarkdownEditorConfig &p_config) +{ + m_previewHelper->setWebPlantUmlEnabled(p_config.getWebPlantUml()); + m_previewHelper->setWebGraphvizEnabled(p_config.getWebGraphviz()); + + const auto srcs = p_config.getInplacePreviewSources(); + m_previewHelper->setInplacePreviewCodeBlocksEnabled(srcs & MarkdownEditorConfig::CodeBlock); + m_previewHelper->setInplacePreviewMathBlocksEnabled(srcs & MarkdownEditorConfig::Math); +} + void MarkdownViewWindow::applySnippet(const QString &p_name) { if (isReadMode()) { diff --git a/src/widgets/markdownviewwindow.h b/src/widgets/markdownviewwindow.h index a0148327..f9212bfa 100644 --- a/src/widgets/markdownviewwindow.h +++ b/src/widgets/markdownviewwindow.h @@ -145,6 +145,8 @@ namespace vnotex bool isReadMode() const; + void updatePreviewHelperFromConfig(const MarkdownEditorConfig &p_config); + template static QSharedPointer headingsToOutline(const QVector &p_headings);