mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
refine edit mode
1. Support "Ctrl+Alt+<N>" to insert title in Markdown; 2. Support Auto Indent; 3. Support Auto List;
This commit is contained in:
parent
acec514418
commit
b0d3e42647
@ -7,6 +7,8 @@ is_expand_tab=true
|
|||||||
highlight_cursor_line=true
|
highlight_cursor_line=true
|
||||||
highlight_selected_word=true
|
highlight_selected_word=true
|
||||||
highlight_searched_word=true
|
highlight_searched_word=true
|
||||||
|
auto_indent=true
|
||||||
|
auto_list=true
|
||||||
current_background_color=System
|
current_background_color=System
|
||||||
current_render_background_color=System
|
current_render_background_color=System
|
||||||
language=System
|
language=System
|
||||||
|
@ -57,6 +57,8 @@ void VConfigManager::initialize()
|
|||||||
m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool();
|
m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool();
|
||||||
m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool();
|
m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool();
|
||||||
m_highlightSearchedWord = getConfigFromSettings("global", "highlight_searched_word").toBool();
|
m_highlightSearchedWord = getConfigFromSettings("global", "highlight_searched_word").toBool();
|
||||||
|
m_autoIndent = getConfigFromSettings("global", "auto_indent").toBool();
|
||||||
|
m_autoList = getConfigFromSettings("global", "auto_list").toBool();
|
||||||
|
|
||||||
readPredefinedColorsFromSettings();
|
readPredefinedColorsFromSettings();
|
||||||
curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString();
|
curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString();
|
||||||
|
@ -81,6 +81,12 @@ public:
|
|||||||
inline bool getHighlightSearchedWord() const;
|
inline bool getHighlightSearchedWord() const;
|
||||||
inline void setHighlightSearchedWord(bool p_searchedWord);
|
inline void setHighlightSearchedWord(bool p_searchedWord);
|
||||||
|
|
||||||
|
inline bool getAutoIndent() const;
|
||||||
|
inline void setAutoIndent(bool p_autoIndent);
|
||||||
|
|
||||||
|
inline bool getAutoList() const;
|
||||||
|
inline void setAutoList(bool p_autoList);
|
||||||
|
|
||||||
inline const QVector<VColor> &getPredefinedColors() const;
|
inline const QVector<VColor> &getPredefinedColors() const;
|
||||||
|
|
||||||
inline const QString &getCurBackgroundColor() const;
|
inline const QString &getCurBackgroundColor() const;
|
||||||
@ -167,6 +173,12 @@ private:
|
|||||||
// Highlight searched word.
|
// Highlight searched word.
|
||||||
bool m_highlightSearchedWord;
|
bool m_highlightSearchedWord;
|
||||||
|
|
||||||
|
// Auto Indent.
|
||||||
|
bool m_autoIndent;
|
||||||
|
|
||||||
|
// Auto List.
|
||||||
|
bool m_autoList;
|
||||||
|
|
||||||
// App defined color
|
// App defined color
|
||||||
QVector<VColor> predefinedColors;
|
QVector<VColor> predefinedColors;
|
||||||
QString curBackgroundColor;
|
QString curBackgroundColor;
|
||||||
@ -362,6 +374,36 @@ inline void VConfigManager::setHighlightSearchedWord(bool p_searchedWord)
|
|||||||
m_highlightSearchedWord);
|
m_highlightSearchedWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getAutoIndent() const
|
||||||
|
{
|
||||||
|
return m_autoIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setAutoIndent(bool p_autoIndent)
|
||||||
|
{
|
||||||
|
if (m_autoIndent == p_autoIndent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_autoIndent = p_autoIndent;
|
||||||
|
setConfigToSettings("global", "auto_indent",
|
||||||
|
m_autoIndent);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getAutoList() const
|
||||||
|
{
|
||||||
|
return m_autoList;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setAutoList(bool p_autoList)
|
||||||
|
{
|
||||||
|
if (m_autoList == p_autoList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_autoList = p_autoList;
|
||||||
|
setConfigToSettings("global", "auto_list",
|
||||||
|
m_autoList);
|
||||||
|
}
|
||||||
|
|
||||||
inline const QVector<VColor>& VConfigManager::getPredefinedColors() const
|
inline const QVector<VColor>& VConfigManager::getPredefinedColors() const
|
||||||
{
|
{
|
||||||
return predefinedColors;
|
return predefinedColors;
|
||||||
|
@ -467,6 +467,20 @@ void VMainWindow::initEditMenu()
|
|||||||
connect(tabStopWidthAct, &QActionGroup::triggered,
|
connect(tabStopWidthAct, &QActionGroup::triggered,
|
||||||
this, &VMainWindow::setTabStopWidth);
|
this, &VMainWindow::setTabStopWidth);
|
||||||
|
|
||||||
|
// Auto Indent.
|
||||||
|
m_autoIndentAct = new QAction(tr("Auto Indent"), this);
|
||||||
|
m_autoIndentAct->setStatusTip(tr("Indent automatically when inserting a new line"));
|
||||||
|
m_autoIndentAct->setCheckable(true);
|
||||||
|
connect(m_autoIndentAct, &QAction::triggered,
|
||||||
|
this, &VMainWindow::changeAutoIndent);
|
||||||
|
|
||||||
|
// Auto List.
|
||||||
|
QAction *autoListAct = new QAction(tr("Auto List"), this);
|
||||||
|
autoListAct->setStatusTip(tr("Continue the list automatically when inserting a new line"));
|
||||||
|
autoListAct->setCheckable(true);
|
||||||
|
connect(autoListAct, &QAction::triggered,
|
||||||
|
this, &VMainWindow::changeAutoList);
|
||||||
|
|
||||||
// Highlight current cursor line.
|
// Highlight current cursor line.
|
||||||
QAction *cursorLineAct = new QAction(tr("Highlight Cursor Line"), this);
|
QAction *cursorLineAct = new QAction(tr("Highlight Cursor Line"), this);
|
||||||
cursorLineAct->setStatusTip(tr("Highlight current cursor line"));
|
cursorLineAct->setStatusTip(tr("Highlight current cursor line"));
|
||||||
@ -494,11 +508,7 @@ void VMainWindow::initEditMenu()
|
|||||||
findReplaceMenu->addAction(m_replaceAllAct);
|
findReplaceMenu->addAction(m_replaceAllAct);
|
||||||
findReplaceMenu->addSeparator();
|
findReplaceMenu->addSeparator();
|
||||||
findReplaceMenu->addAction(searchedWordAct);
|
findReplaceMenu->addAction(searchedWordAct);
|
||||||
if (vconfig.getHighlightSearchedWord()) {
|
searchedWordAct->setChecked(vconfig.getHighlightSearchedWord());
|
||||||
searchedWordAct->setChecked(true);
|
|
||||||
} else {
|
|
||||||
searchedWordAct->setChecked(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
editMenu->addSeparator();
|
editMenu->addSeparator();
|
||||||
m_findReplaceAct->setEnabled(false);
|
m_findReplaceAct->setEnabled(false);
|
||||||
@ -532,21 +542,26 @@ void VMainWindow::initEditMenu()
|
|||||||
default:
|
default:
|
||||||
qWarning() << "unsupported tab stop width" << tabStopWidth << "in config";
|
qWarning() << "unsupported tab stop width" << tabStopWidth << "in config";
|
||||||
}
|
}
|
||||||
initEditorBackgroundMenu(editMenu);
|
|
||||||
editMenu->addSeparator();
|
editMenu->addAction(m_autoIndentAct);
|
||||||
editMenu->addAction(cursorLineAct);
|
m_autoIndentAct->setChecked(vconfig.getAutoIndent());
|
||||||
if (vconfig.getHighlightCursorLine()) {
|
|
||||||
cursorLineAct->setChecked(true);
|
editMenu->addAction(autoListAct);
|
||||||
} else {
|
if (vconfig.getAutoList()) {
|
||||||
cursorLineAct->setChecked(false);
|
// Let the trigger handler to trigger m_autoIndentAct, too.
|
||||||
|
autoListAct->trigger();
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(!(autoListAct->isChecked() && !m_autoIndentAct->isChecked()));
|
||||||
|
|
||||||
|
editMenu->addSeparator();
|
||||||
|
|
||||||
|
initEditorBackgroundMenu(editMenu);
|
||||||
|
|
||||||
|
editMenu->addAction(cursorLineAct);
|
||||||
|
cursorLineAct->setChecked(vconfig.getHighlightCursorLine());
|
||||||
|
|
||||||
editMenu->addAction(selectedWordAct);
|
editMenu->addAction(selectedWordAct);
|
||||||
if (vconfig.getHighlightSelectedWord()) {
|
selectedWordAct->setChecked(vconfig.getHighlightSelectedWord());
|
||||||
selectedWordAct->setChecked(true);
|
|
||||||
} else {
|
|
||||||
selectedWordAct->setChecked(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::initDockWindows()
|
void VMainWindow::initDockWindows()
|
||||||
@ -1075,3 +1090,21 @@ void VMainWindow::closeCurrentFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMainWindow::changeAutoIndent(bool p_checked)
|
||||||
|
{
|
||||||
|
vconfig.setAutoIndent(p_checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMainWindow::changeAutoList(bool p_checked)
|
||||||
|
{
|
||||||
|
vconfig.setAutoList(p_checked);
|
||||||
|
if (p_checked) {
|
||||||
|
if (!m_autoIndentAct->isChecked()) {
|
||||||
|
m_autoIndentAct->trigger();
|
||||||
|
}
|
||||||
|
m_autoIndentAct->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
m_autoIndentAct->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@ private slots:
|
|||||||
void enableMermaid(bool p_checked);
|
void enableMermaid(bool p_checked);
|
||||||
void enableMathjax(bool p_checked);
|
void enableMathjax(bool p_checked);
|
||||||
void handleCaptainModeChanged(bool p_enabled);
|
void handleCaptainModeChanged(bool p_enabled);
|
||||||
|
void changeAutoIndent(bool p_checked);
|
||||||
|
void changeAutoList(bool p_checked);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
||||||
@ -148,6 +150,8 @@ private:
|
|||||||
QAction *m_replaceFindAct;
|
QAction *m_replaceFindAct;
|
||||||
QAction *m_replaceAllAct;
|
QAction *m_replaceAllAct;
|
||||||
|
|
||||||
|
QAction *m_autoIndentAct;
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
QMenu *viewMenu;
|
QMenu *viewMenu;
|
||||||
|
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
#include "vdownloader.h"
|
#include "vdownloader.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
#include "vmdedit.h"
|
#include "vmdedit.h"
|
||||||
|
#include "vconfigmanager.h"
|
||||||
|
|
||||||
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
const QString VMdEditOperations::c_defaultImageTitle = "image";
|
const QString VMdEditOperations::c_defaultImageTitle = "image";
|
||||||
|
|
||||||
@ -178,7 +181,25 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
int modifiers = p_event->modifiers();
|
||||||
switch (p_event->key()) {
|
switch (p_event->key()) {
|
||||||
|
case Qt::Key_1:
|
||||||
|
case Qt::Key_2:
|
||||||
|
case Qt::Key_3:
|
||||||
|
case Qt::Key_4:
|
||||||
|
case Qt::Key_5:
|
||||||
|
case Qt::Key_6:
|
||||||
|
{
|
||||||
|
if (modifiers == (Qt::ControlModifier | Qt::AltModifier)) {
|
||||||
|
// Ctrl + Alt + <N>: insert title at level <N>.
|
||||||
|
if (insertTitle(p_event->key() - Qt::Key_0)) {
|
||||||
|
p_event->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Qt::Key_Tab:
|
case Qt::Key_Tab:
|
||||||
{
|
{
|
||||||
if (handleKeyTab(p_event)) {
|
if (handleKeyTab(p_event)) {
|
||||||
@ -267,6 +288,14 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Qt::Key_Return:
|
||||||
|
{
|
||||||
|
if (handleKeyReturn(p_event)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -612,6 +641,73 @@ bool VMdEditOperations::handleKeyEsc(QKeyEvent *p_event)
|
|||||||
return accept;
|
return accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event)
|
||||||
|
{
|
||||||
|
if (p_event->modifiers() & Qt::ControlModifier) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
if (vconfig.getAutoIndent()) {
|
||||||
|
ret = true;
|
||||||
|
// Indent the new line as previous line.
|
||||||
|
insertNewBlockWithIndent();
|
||||||
|
|
||||||
|
// Continue the list from previous line.
|
||||||
|
if (vconfig.getAutoList()) {
|
||||||
|
insertListMarkAsPreviousLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMdEditOperations::insertNewBlockWithIndent()
|
||||||
|
{
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
cursor.removeSelectedText();
|
||||||
|
QTextBlock block = cursor.block();
|
||||||
|
QString text = block.text();
|
||||||
|
QRegExp regExp("(^\\s*)");
|
||||||
|
regExp.indexIn(text);
|
||||||
|
Q_ASSERT(regExp.captureCount() == 1);
|
||||||
|
QString leadingSpaces = regExp.capturedTexts()[1];
|
||||||
|
cursor.insertBlock();
|
||||||
|
cursor.insertText(leadingSpaces);
|
||||||
|
cursor.endEditBlock();
|
||||||
|
m_editor->setTextCursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMdEditOperations::insertListMarkAsPreviousLine()
|
||||||
|
{
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
QTextBlock block = cursor.block();
|
||||||
|
QTextBlock preBlock = block.previous();
|
||||||
|
QString text = preBlock.text();
|
||||||
|
QRegExp regExp("^\\s*(-|\\d+\\.)\\s");
|
||||||
|
int regIdx = regExp.indexIn(text);
|
||||||
|
if (regIdx != -1) {
|
||||||
|
Q_ASSERT(regExp.captureCount() == 1);
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
QString markText = regExp.capturedTexts()[1];
|
||||||
|
if (markText == "-") {
|
||||||
|
// Insert - in front.
|
||||||
|
cursor.insertText("- ");
|
||||||
|
} else {
|
||||||
|
// markText is like "123.".
|
||||||
|
Q_ASSERT(markText.endsWith('.'));
|
||||||
|
bool ok = false;
|
||||||
|
int num = markText.left(markText.size() - 1).toInt(&ok, 10);
|
||||||
|
Q_ASSERT(ok);
|
||||||
|
num++;
|
||||||
|
cursor.insertText(QString::number(num, 10) + ". ");
|
||||||
|
}
|
||||||
|
cursor.endEditBlock();
|
||||||
|
m_editor->setTextCursor(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool VMdEditOperations::handleKeyPressVim(QKeyEvent *p_event)
|
bool VMdEditOperations::handleKeyPressVim(QKeyEvent *p_event)
|
||||||
{
|
{
|
||||||
int modifiers = p_event->modifiers();
|
int modifiers = p_event->modifiers();
|
||||||
@ -1004,3 +1100,37 @@ void VMdEditOperations::setKeyState(KeyState p_state)
|
|||||||
m_keyState = p_state;
|
m_keyState = p_state;
|
||||||
emit keyStateChanged(m_keyState);
|
emit keyStateChanged(m_keyState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMdEditOperations::insertTitle(int p_level)
|
||||||
|
{
|
||||||
|
Q_ASSERT(p_level > 0 && p_level < 7);
|
||||||
|
QTextDocument *doc = m_editor->document();
|
||||||
|
QString titleMark(p_level, '#');
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
// Insert title # in front of the selected lines.
|
||||||
|
int start = cursor.selectionStart();
|
||||||
|
int end = cursor.selectionEnd();
|
||||||
|
int startBlock = doc->findBlock(start).blockNumber();
|
||||||
|
int endBlock = doc->findBlock(end).blockNumber();
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
cursor.clearSelection();
|
||||||
|
for (int i = startBlock; i <= endBlock; ++i) {
|
||||||
|
QTextBlock block = doc->findBlockByNumber(i);
|
||||||
|
cursor.setPosition(block.position(), QTextCursor::MoveAnchor);
|
||||||
|
cursor.insertText(titleMark + " ");
|
||||||
|
}
|
||||||
|
cursor.movePosition(QTextCursor::EndOfBlock);
|
||||||
|
cursor.endEditBlock();
|
||||||
|
} else {
|
||||||
|
// Insert title # in front of current block.
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
cursor.movePosition(QTextCursor::StartOfBlock);
|
||||||
|
cursor.insertText(titleMark + " ");
|
||||||
|
cursor.movePosition(QTextCursor::EndOfBlock);
|
||||||
|
cursor.endEditBlock();
|
||||||
|
}
|
||||||
|
m_editor->setTextCursor(cursor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -39,11 +39,15 @@ private:
|
|||||||
bool handleKeyU(QKeyEvent *p_event);
|
bool handleKeyU(QKeyEvent *p_event);
|
||||||
bool handleKeyW(QKeyEvent *p_event);
|
bool handleKeyW(QKeyEvent *p_event);
|
||||||
bool handleKeyEsc(QKeyEvent *p_event);
|
bool handleKeyEsc(QKeyEvent *p_event);
|
||||||
|
bool handleKeyReturn(QKeyEvent *p_event);
|
||||||
bool handleKeyPressVim(QKeyEvent *p_event);
|
bool handleKeyPressVim(QKeyEvent *p_event);
|
||||||
bool handleKeyBracketLeft(QKeyEvent *p_event);
|
bool handleKeyBracketLeft(QKeyEvent *p_event);
|
||||||
bool shouldTriggerVimMode(QKeyEvent *p_event);
|
bool shouldTriggerVimMode(QKeyEvent *p_event);
|
||||||
int keySeqToNumber(const QList<QString> &p_seq);
|
int keySeqToNumber(const QList<QString> &p_seq);
|
||||||
bool suffixNumAllowed(const QList<QString> &p_seq);
|
bool suffixNumAllowed(const QList<QString> &p_seq);
|
||||||
|
bool insertTitle(int p_level);
|
||||||
|
void insertNewBlockWithIndent();
|
||||||
|
void insertListMarkAsPreviousLine();
|
||||||
|
|
||||||
QTimer *m_pendingTimer;
|
QTimer *m_pendingTimer;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user