diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 3d8fcab4..7dd4f752 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -5,3 +5,5 @@ pre_template_path=:/resources/pre_template.html post_template_path=:/resources/post_template.html template_css_url=qrc:/resources/markdown.css current_notebook=0 +tab_stop_width=4 +is_expand_tab=1 diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index cb4a3d43..35fb2b30 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -50,6 +50,9 @@ void VConfigManager::initialize() HOEDOWN_EXT_QUOTE | HOEDOWN_EXT_MATH); mdConverterType = (MarkdownConverterType)getConfigFromSettings("global", "markdown_converter").toInt(); + tabStopWidth = getConfigFromSettings("global", "tab_stop_width").toInt(); + isExpandTab = getConfigFromSettings("global", "is_expand_tab").toBool(); + // Update notebooks readNotebookFromSettings(); diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 2bf06bfb..fb30fdf2 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -62,6 +62,11 @@ public: inline QString getPreTemplatePath() const; inline QString getPostTemplatePath() const; + inline int getTabStopWidth() const; + inline void setTabStopWidth(int tabStopWidth); + inline bool getIsExpandTab() const; + inline void setIsExpandTab(bool isExpandTab); + private: void updateMarkdownEditStyle(); QVariant getConfigFromSettings(const QString §ion, const QString &key); @@ -86,6 +91,11 @@ private: hoedown_extensions markdownExtensions; MarkdownConverterType mdConverterType; + // Num of spaces + int tabStopWidth; + // Expand tab to @tabStopWidth spaces + bool isExpandTab; + // The name of the config file in each directory static const QString dirConfigFileName; // The name of the default configuration file @@ -186,4 +196,32 @@ inline void VConfigManager::setMarkdownConverterType(MarkdownConverterType type) setConfigToSettings("global", "markdown_converter", type); } +inline int VConfigManager::getTabStopWidth() const +{ + return tabStopWidth; +} + +inline bool VConfigManager::getIsExpandTab() const +{ + return isExpandTab; +} + +inline void VConfigManager::setTabStopWidth(int tabStopWidth) +{ + if (tabStopWidth == this->tabStopWidth) { + return; + } + this->tabStopWidth = tabStopWidth; + setConfigToSettings("global", "tab_stop_width", tabStopWidth); +} + +inline void VConfigManager::setIsExpandTab(bool isExpandTab) +{ + if (isExpandTab == this->isExpandTab) { + return; + } + this->isExpandTab = isExpandTab; + setConfigToSettings("global", "is_expand_tab", this->isExpandTab); +} + #endif // VCONFIGMANAGER_H diff --git a/src/vedit.cpp b/src/vedit.cpp index 939e2d8f..e1bd3cd5 100644 --- a/src/vedit.cpp +++ b/src/vedit.cpp @@ -13,18 +13,46 @@ VEdit::VEdit(VNoteFile *noteFile, QWidget *parent) setPalette(vconfig.getMdEditPalette()); setFont(vconfig.getMdEditFont()); setAcceptRichText(false); - mdHighlighter = new HGMarkdownHighlighter(vconfig.getMdHighlightingStyles(), 500, document()); } else { setFont(vconfig.getBaseEditFont()); setAutoFormatting(QTextEdit::AutoBulletList); } + + updateTabSettings(); +} + +void VEdit::updateTabSettings() +{ + switch (noteFile->docType) { + case DocType::Markdown: + if (vconfig.getTabStopWidth() > 0) { + QFontMetrics metrics(vconfig.getMdEditFont()); + setTabStopWidth(vconfig.getTabStopWidth() * metrics.width(' ')); + } + break; + case DocType::Html: + if (vconfig.getTabStopWidth() > 0) { + QFontMetrics metrics(vconfig.getBaseEditFont()); + setTabStopWidth(vconfig.getTabStopWidth() * metrics.width(' ')); + } + break; + default: + qWarning() << "error: unknown doc type" << int(noteFile->docType); + return; + } + + isExpandTab = vconfig.getIsExpandTab(); + if (isExpandTab && (vconfig.getTabStopWidth() > 0)) { + tabSpaces = QString(vconfig.getTabStopWidth(), ' '); + } } void VEdit::beginEdit() { setReadOnly(false); + updateTabSettings(); switch (noteFile->docType) { case DocType::Html: setHtml(noteFile->content); @@ -69,3 +97,14 @@ void VEdit::reloadFile() qWarning() << "error: unknown doc type" << int(noteFile->docType); } } + +void VEdit::keyPressEvent(QKeyEvent *event) +{ + if ((event->key() == Qt::Key_Tab) && isExpandTab) { + QTextCursor cursor(document()); + cursor.setPosition(textCursor().position()); + cursor.insertText(tabSpaces); + return; + } + QTextEdit::keyPressEvent(event); +} diff --git a/src/vedit.h b/src/vedit.h index a368db78..86db918b 100644 --- a/src/vedit.h +++ b/src/vedit.h @@ -23,12 +23,14 @@ public: void reloadFile(); -signals: - -public slots: - +protected: + void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; private: + void updateTabSettings(); + + bool isExpandTab; + QString tabSpaces; VNoteFile *noteFile; HGMarkdownHighlighter *mdHighlighter; }; diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 96c41199..2703937a 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -183,6 +183,28 @@ void VMainWindow::initActions() aboutQtAct->setStatusTip(tr("Show information about Qt")); connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); + + expandTabAct = new QAction(tr("&Expand tab"), this); + expandTabAct->setStatusTip(tr("Expand tab to spaces")); + expandTabAct->setCheckable(true); + connect(expandTabAct, &QAction::triggered, + this, &VMainWindow::changeExpandTab); + + tabStopWidthAct = new QActionGroup(this); + twoSpaceTabAct = new QAction(tr("2 spaces"), tabStopWidthAct); + twoSpaceTabAct->setStatusTip(tr("Expand tab to 2 spaces")); + twoSpaceTabAct->setCheckable(true); + twoSpaceTabAct->setData(2); + fourSpaceTabAct = new QAction(tr("4 spaces"), tabStopWidthAct); + fourSpaceTabAct->setStatusTip(tr("Expand tab to 4 spaces")); + fourSpaceTabAct->setCheckable(true); + fourSpaceTabAct->setData(4); + eightSpaceTabAct = new QAction(tr("8 spaces"), tabStopWidthAct); + eightSpaceTabAct->setStatusTip(tr("Expand tab to 8 spaces")); + eightSpaceTabAct->setCheckable(true); + eightSpaceTabAct->setData(8); + connect(tabStopWidthAct, &QActionGroup::triggered, + this, &VMainWindow::setTabStopWidth); } void VMainWindow::initToolBar() @@ -205,6 +227,32 @@ void VMainWindow::initMenuBar() // File Menu fileMenu->addAction(importNoteAct); + // Edit Menu + editMenu->addAction(expandTabAct); + if (vconfig.getIsExpandTab()) { + expandTabAct->setChecked(true); + } else { + expandTabAct->setChecked(false); + } + QMenu *tabStopWidthMenu = editMenu->addMenu(tr("Tab stop width")); + tabStopWidthMenu->addAction(twoSpaceTabAct); + tabStopWidthMenu->addAction(fourSpaceTabAct); + tabStopWidthMenu->addAction(eightSpaceTabAct); + int tabStopWidth = vconfig.getTabStopWidth(); + switch (tabStopWidth) { + case 2: + twoSpaceTabAct->setChecked(true); + break; + case 4: + fourSpaceTabAct->setChecked(true); + break; + case 8: + eightSpaceTabAct->setChecked(true); + break; + default: + qWarning() << "error: unsupported tab stop width" << tabStopWidth << "in config"; + } + // Markdown Menu QMenu *converterMenu = markdownMenu->addMenu(tr("&Converter")); converterMenu->addAction(hoedownAct); @@ -424,3 +472,16 @@ void VMainWindow::aboutMessage() tr("VNote is a Vim-inspired note taking application for Markdown.\n" "Visit https://github.com/tamlok/vnote.git for more information.")); } + +void VMainWindow::changeExpandTab(bool checked) +{ + vconfig.setIsExpandTab(checked); +} + +void VMainWindow::setTabStopWidth(QAction *action) +{ + if (!action) { + return; + } + vconfig.setTabStopWidth(action->data().toInt()); +} diff --git a/src/vmainwindow.h b/src/vmainwindow.h index c902fbfc..d61f4e37 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -40,6 +40,8 @@ private slots: void importNoteFromFile(); void changeMarkdownConverter(QAction *action); void aboutMessage(); + void changeExpandTab(bool checked); + void setTabStopWidth(QAction *action); signals: void curNotebookChanged(const QString ¬ebookName); @@ -79,6 +81,11 @@ private: QAction *hoedownAct; QAction *aboutAct; QAction *aboutQtAct; + QAction *expandTabAct; + QActionGroup *tabStopWidthAct; + QAction *twoSpaceTabAct; + QAction *fourSpaceTabAct; + QAction *eightSpaceTabAct; }; #endif // VMAINWINDOW_H