diff --git a/libs/vtextedit b/libs/vtextedit index 01fb4118..5fe5d4be 160000 --- a/libs/vtextedit +++ b/libs/vtextedit @@ -1 +1 @@ -Subproject commit 01fb4118f566ff7a71db67af72de1d586a0e9ee5 +Subproject commit 5fe5d4be7191de58fd1c2411b1ff97bcbecfaa3d diff --git a/src/core/buffer/buffer.cpp b/src/core/buffer/buffer.cpp index 283a62b4..ba4fe47a 100644 --- a/src/core/buffer/buffer.cpp +++ b/src/core/buffer/buffer.cpp @@ -212,7 +212,7 @@ Buffer::OperationCode Buffer::save(bool p_force) try { m_provider->write(m_content); } catch (Exception &p_e) { - qWarning() << "failed to write the buffer content" << getPath(); + qWarning() << "failed to write the buffer content" << getPath() << p_e.what(); return OperationCode::Failed; } @@ -327,7 +327,7 @@ void Buffer::autoSave() try { writeBackupFile(); } catch (Exception &p_e) { - qWarning() << "AutoSave failed to write backup file, retry later"; + qWarning() << "AutoSave failed to write backup file, retry later" << p_e.what(); } break; } diff --git a/src/core/configmgr.cpp b/src/core/configmgr.cpp index f042c3e1..1fcad027 100644 --- a/src/core/configmgr.cpp +++ b/src/core/configmgr.cpp @@ -24,7 +24,7 @@ using namespace vnotex; #ifndef QT_NO_DEBUG -#define VX_DEBUG_WEB +// #define VX_DEBUG_WEB #endif const QString ConfigMgr::c_orgName = "VNote"; diff --git a/src/core/htmltemplatehelper.cpp b/src/core/htmltemplatehelper.cpp index 5a5ec44e..f1edc831 100644 --- a/src/core/htmltemplatehelper.cpp +++ b/src/core/htmltemplatehelper.cpp @@ -24,6 +24,7 @@ QString WebGlobalOptions::toJavascriptObject() const + QString("htmlTagEnabled: %1,\n").arg(Utils::boolToString(m_htmlTagEnabled)) + QString("autoBreakEnabled: %1,\n").arg(Utils::boolToString(m_autoBreakEnabled)) + QString("linkifyEnabled: %1,\n").arg(Utils::boolToString(m_linkifyEnabled)) + + QString("indentFirstLineEnabled: %1,\n").arg(Utils::boolToString(m_indentFirstLineEnabled)) + QString("sectionNumberEnabled: %1\n").arg(Utils::boolToString(m_sectionNumberEnabled)) + QStringLiteral("}"); } @@ -161,6 +162,7 @@ void HtmlTemplateHelper::updateMarkdownViewerTemplate(const MarkdownEditorConfig opts.m_htmlTagEnabled = p_config.getHtmlTagEnabled(); opts.m_autoBreakEnabled = p_config.getAutoBreakEnabled(); opts.m_linkifyEnabled = p_config.getLinkifyEnabled(); + opts.m_indentFirstLineEnabled = p_config.getIndentFirstLineEnabled(); fillGlobalOptions(s_markdownViewerTemplate.m_template, opts); } diff --git a/src/core/htmltemplatehelper.h b/src/core/htmltemplatehelper.h index ded17b4d..a421edbc 100644 --- a/src/core/htmltemplatehelper.h +++ b/src/core/htmltemplatehelper.h @@ -26,6 +26,8 @@ namespace vnotex bool m_linkifyEnabled = true; + bool m_indentFirstLineEnabled = false; + QString toJavascriptObject() const; }; diff --git a/src/core/mainconfig.cpp b/src/core/mainconfig.cpp index 1451be95..3bfcabc3 100644 --- a/src/core/mainconfig.cpp +++ b/src/core/mainconfig.cpp @@ -117,5 +117,4 @@ QString MainConfig::getVersion(const QJsonObject &p_jobj) void MainConfig::doVersionSpecificOverride() { // In a new version, we may want to change one value by force. - m_coreConfig->setTheme(QStringLiteral("moonlight")); } diff --git a/src/core/markdowneditorconfig.cpp b/src/core/markdowneditorconfig.cpp index 51562513..4ef0fcda 100644 --- a/src/core/markdowneditorconfig.cpp +++ b/src/core/markdowneditorconfig.cpp @@ -46,6 +46,7 @@ void MarkdownEditorConfig::init(const QJsonObject &p_app, const QJsonObject &p_u m_htmlTagEnabled = READBOOL(QStringLiteral("html_tag")); m_autoBreakEnabled = READBOOL(QStringLiteral("auto_break")); m_linkifyEnabled = READBOOL(QStringLiteral("linkify")); + m_indentFirstLineEnabled = READBOOL(QStringLiteral("indent_first_line")); } QJsonObject MarkdownEditorConfig::toJson() const @@ -69,6 +70,7 @@ QJsonObject MarkdownEditorConfig::toJson() const obj[QStringLiteral("html_tag")] = m_htmlTagEnabled; obj[QStringLiteral("auto_break")] = m_autoBreakEnabled; obj[QStringLiteral("linkify")] = m_linkifyEnabled; + obj[QStringLiteral("indent_first_line")] = m_indentFirstLineEnabled; return obj; } @@ -229,6 +231,16 @@ void MarkdownEditorConfig::setLinkifyEnabled(bool p_enabled) updateConfig(m_linkifyEnabled, p_enabled, this); } +bool MarkdownEditorConfig::getIndentFirstLineEnabled() const +{ + return m_indentFirstLineEnabled; +} + +void MarkdownEditorConfig::setIndentFirstLineEnabled(bool p_enabled) +{ + updateConfig(m_indentFirstLineEnabled, p_enabled, this); +} + QString MarkdownEditorConfig::sectionNumberModeToString(SectionNumberMode p_mode) const { switch (p_mode) { diff --git a/src/core/markdowneditorconfig.h b/src/core/markdowneditorconfig.h index 28525b00..c0473bbf 100644 --- a/src/core/markdowneditorconfig.h +++ b/src/core/markdowneditorconfig.h @@ -81,6 +81,9 @@ namespace vnotex bool getLinkifyEnabled() const; void setLinkifyEnabled(bool p_enabled); + bool getIndentFirstLineEnabled() const; + void setIndentFirstLineEnabled(bool p_enabled); + private: QString sectionNumberModeToString(SectionNumberMode p_mode) const; SectionNumberMode stringToSectionNumberMode(const QString &p_str) const; @@ -131,6 +134,9 @@ namespace vnotex // Whether convert URL-like text to links. bool m_linkifyEnabled = true; + + // Whether indent the first line of a paragraph. + bool m_indentFirstLineEnabled = false; }; } diff --git a/src/data/core/Info.plist b/src/data/core/Info.plist index 89b9899a..9eeb37d1 100644 --- a/src/data/core/Info.plist +++ b/src/data/core/Info.plist @@ -2,6 +2,22 @@ + CFBundleDocumentTypes + + + CFBundleTypeIconFile + vnote.icns + CFBundleTypeName + VNote Document + CFBundleTypeRole + Editor + LSItemContentTypes + + public.plain-text + net.daringfireball.markdown + + + CFBundleExecutable vnote CFBundleShortVersionString diff --git a/src/data/core/vnotex.json b/src/data/core/vnotex.json index 1e0699fb..c285437f 100644 --- a/src/data/core/vnotex.json +++ b/src/data/core/vnotex.json @@ -245,7 +245,9 @@ "//comment" : "Whether auto break a line with '\\n'", "auto_break" : false, "//comment" : "Whether convert URL-like text to links", - "linkify" : true + "linkify" : true, + "//comment" : "Whether add indentation to the first line of paragraph", + "indent_first_line" : false } }, "widget" : { diff --git a/src/data/extra/themes/moonlight/interface.qss b/src/data/extra/themes/moonlight/interface.qss index 5f155684..fa2cb54f 100644 --- a/src/data/extra/themes/moonlight/interface.qss +++ b/src/data/extra/themes/moonlight/interface.qss @@ -897,6 +897,11 @@ QAbstractSpinBox { selection-background-color: @widgets#qspinbox#selection#bg; } +QAbstractSpinBox:disabled { + color: @widgets#qspinbox#disabled#fg; + background-color: @widgets#qspinbox#disabled#bg; +} + QAbstractSpinBox:focus { border: 2px solid @widgets#qspinbox#focus#border; background-color: @widgets#qspinbox#focus#bg; diff --git a/src/data/extra/themes/moonlight/palette.json b/src/data/extra/themes/moonlight/palette.json index 8124605b..9e9f83c1 100644 --- a/src/data/extra/themes/moonlight/palette.json +++ b/src/data/extra/themes/moonlight/palette.json @@ -516,6 +516,10 @@ "border" : "@base#content#border", "fg" : "@base#content#fg", "bg" : "@base#content#bg", + "disabled" : { + "fg" : "@base#content#disabled#fg", + "bg" : "@base#content#disabled#bg" + }, "selection" : { "fg" : "@base#content#selection#fg", "bg" : "@base#content#selection#bg" diff --git a/src/data/extra/web/css/globalstyles.css b/src/data/extra/web/css/globalstyles.css index 429bbe96..9733b67f 100644 --- a/src/data/extra/web/css/globalstyles.css +++ b/src/data/extra/web/css/globalstyles.css @@ -81,3 +81,7 @@ visibility: visible; vertical-align: middle; } + +#vx-content.vx-indent-first-line p { + text-indent: 2em; +} diff --git a/src/data/extra/web/js/markdownit.js b/src/data/extra/web/js/markdownit.js index 3b07b546..665b722a 100644 --- a/src/data/extra/web/js/markdownit.js +++ b/src/data/extra/web/js/markdownit.js @@ -240,6 +240,10 @@ class MarkdownIt extends VxWorker { } registerInternal() { + this.vnotex.on('ready', () => { + this.setConstrainImageWidthEnabled(window.vxOptions.constrainImageWidthEnabled); + this.setIndentFirstLineEnabled(window.vxOptions.indentFirstLineEnabled); + }); this.vnotex.on('markdownTextUpdated', (p_text) => { this.render(this.vnotex.contentContainer, p_text, @@ -247,6 +251,24 @@ class MarkdownIt extends VxWorker { }); } + setConstrainImageWidthEnabled(p_enabled) { + let constrainClass = 'vx-constrain-image-width'; + if (p_enabled) { + this.vnotex.contentContainer.classList.add(constrainClass); + } else { + this.vnotex.contentContainer.classList.remove(constrainClass); + } + } + + setIndentFirstLineEnabled(p_enabled) { + let constrainClass = 'vx-indent-first-line'; + if (p_enabled) { + this.vnotex.contentContainer.classList.add(constrainClass); + } else { + this.vnotex.contentContainer.classList.remove(constrainClass); + } + } + // Render Markdown @p_text to HTML in @p_node. // @p_finishCbStr will be called after finishing loading new content nodes. // This could prevent Mermaid Gantt from negative width error. diff --git a/src/data/extra/web/js/utils.js b/src/data/extra/web/js/utils.js index 4eaee62d..d1a15d6c 100644 --- a/src/data/extra/web/js/utils.js +++ b/src/data/extra/web/js/utils.js @@ -111,6 +111,6 @@ class Utils { } static headingSequenceRegExp() { - return /^\d(?:\.\d)*\.? /; + return /^\d{1,3}(?:\.\d+)*\.? /; } } diff --git a/src/data/extra/web/js/vnotex.js b/src/data/extra/web/js/vnotex.js index d9b73613..e1377498 100644 --- a/src/data/extra/web/js/vnotex.js +++ b/src/data/extra/web/js/vnotex.js @@ -136,7 +136,6 @@ class VNoteX extends EventEmitter { } setBasicMarkdownRendered() { - this.setConstrainImageWidthEnabled(window.vxOptions.constrainImageWidthEnabled); this.emit('basicMarkdownRendered'); } @@ -210,15 +209,6 @@ class VNoteX extends EventEmitter { } } - setConstrainImageWidthEnabled(p_enabled) { - let constrainClass = 'vx-constrain-image-width'; - if (p_enabled) { - this.contentContainer.classList.add(constrainClass); - } else { - this.contentContainer.classList.remove(constrainClass); - } - } - scroll(p_up) { EasyAccess.scroll(p_up); } diff --git a/src/widgets/dialogs/dialog.cpp b/src/widgets/dialogs/dialog.cpp index 4fc17a87..e8a93f26 100644 --- a/src/widgets/dialogs/dialog.cpp +++ b/src/widgets/dialogs/dialog.cpp @@ -76,6 +76,10 @@ QDialogButtonBox *Dialog::getDialogButtonBox() const void Dialog::setInformationText(const QString &p_text, InformationLevel p_level) { if (!m_infoTextEdit) { + if (p_text.isEmpty()) { + return; + } + m_infoTextEdit = new QPlainTextEdit(this); m_infoTextEdit->setReadOnly(true); m_infoTextEdit->setMaximumHeight(m_infoTextEdit->minimumSizeHint().height()); @@ -83,7 +87,10 @@ void Dialog::setInformationText(const QString &p_text, InformationLevel p_level) } m_infoTextEdit->setPlainText(p_text); - m_infoTextEdit->setVisible(!p_text.isEmpty()); + + const bool visible = !p_text.isEmpty(); + const bool needResize = visible != m_infoTextEdit->isVisible(); + m_infoTextEdit->setVisible(visible); // Change the style. const char *level = ""; @@ -102,7 +109,9 @@ void Dialog::setInformationText(const QString &p_text, InformationLevel p_level) } WidgetUtils::setPropertyDynamically(m_infoTextEdit, PropertyDefs::s_state, level); - WidgetUtils::updateSize(this); + if (needResize) { + WidgetUtils::updateSize(this); + } } void Dialog::acceptedButtonClicked() diff --git a/src/widgets/dialogs/settings/markdowneditorpage.cpp b/src/widgets/dialogs/settings/markdowneditorpage.cpp index 3f0f63e7..f0c912fa 100644 --- a/src/widgets/dialogs/settings/markdowneditorpage.cpp +++ b/src/widgets/dialogs/settings/markdowneditorpage.cpp @@ -66,6 +66,8 @@ void MarkdownEditorPage::loadInternal() m_autoBreakCheckBox->setChecked(markdownConfig.getAutoBreakEnabled()); m_linkifyCheckBox->setChecked(markdownConfig.getLinkifyEnabled()); + + m_indentFirstLineCheckBox->setChecked(markdownConfig.getIndentFirstLineEnabled()); } void MarkdownEditorPage::saveInternal() @@ -97,6 +99,8 @@ void MarkdownEditorPage::saveInternal() markdownConfig.setLinkifyEnabled(m_linkifyCheckBox->isChecked()); + markdownConfig.setIndentFirstLineEnabled(m_indentFirstLineCheckBox->isChecked()); + EditorPage::notifyEditorConfigChange(); } @@ -164,6 +168,16 @@ QGroupBox *MarkdownEditorPage::setupReadGroup() this, &MarkdownEditorPage::pageIsChanged); } + { + const QString label(tr("Indent first line")); + m_indentFirstLineCheckBox = WidgetsFactory::createCheckBox(label, box); + m_indentFirstLineCheckBox->setToolTip(tr("Indent the first line of each paragraph")); + layout->addRow(m_indentFirstLineCheckBox); + addSearchItem(label, m_indentFirstLineCheckBox->toolTip(), m_indentFirstLineCheckBox); + connect(m_indentFirstLineCheckBox, &QCheckBox::stateChanged, + this, &MarkdownEditorPage::pageIsChanged); + } + return box; } diff --git a/src/widgets/dialogs/settings/markdowneditorpage.h b/src/widgets/dialogs/settings/markdowneditorpage.h index bf64ab36..65425198 100644 --- a/src/widgets/dialogs/settings/markdowneditorpage.h +++ b/src/widgets/dialogs/settings/markdowneditorpage.h @@ -47,6 +47,8 @@ namespace vnotex QCheckBox *m_linkifyCheckBox = nullptr; + QCheckBox *m_indentFirstLineCheckBox = nullptr; + QDoubleSpinBox *m_zoomFactorSpinBox = nullptr; QComboBox *m_sectionNumberComboBox = nullptr; diff --git a/src/widgets/editors/markdowneditor.h b/src/widgets/editors/markdowneditor.h index efd81d17..f9be76ff 100644 --- a/src/widgets/editors/markdowneditor.h +++ b/src/widgets/editors/markdowneditor.h @@ -187,7 +187,7 @@ namespace vnotex QTimer *m_sectionNumberTimer = nullptr; // Used to detect the config change and do a clean up. - bool m_sectionNumberEnabled = true; + bool m_sectionNumberEnabled = false; OverrideState m_overriddenSectionNumber = OverrideState::NoOverride; }; diff --git a/src/widgets/markdownviewwindow.cpp b/src/widgets/markdownviewwindow.cpp index 5aeeb1c4..ad253cc2 100644 --- a/src/widgets/markdownviewwindow.cpp +++ b/src/widgets/markdownviewwindow.cpp @@ -399,7 +399,7 @@ void MarkdownViewWindow::setupViewer() // Status widget. { // TODO: implement a real status widget for viewer. - auto label = new QLabel(tr("Markdown Web Viewer"), this); + auto label = new QLabel(tr("Markdown Viewer"), this); label->setAlignment(Qt::AlignRight | Qt::AlignVCenter); m_viewerStatusWidget.reset(label); getMainStatusWidget()->addWidget(m_viewerStatusWidget.get());