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_selected_word=true
|
||||
highlight_searched_word=true
|
||||
auto_indent=true
|
||||
auto_list=true
|
||||
current_background_color=System
|
||||
current_render_background_color=System
|
||||
language=System
|
||||
|
@ -57,6 +57,8 @@ void VConfigManager::initialize()
|
||||
m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool();
|
||||
m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_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();
|
||||
curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString();
|
||||
|
@ -81,6 +81,12 @@ public:
|
||||
inline bool getHighlightSearchedWord() const;
|
||||
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 QString &getCurBackgroundColor() const;
|
||||
@ -167,6 +173,12 @@ private:
|
||||
// Highlight searched word.
|
||||
bool m_highlightSearchedWord;
|
||||
|
||||
// Auto Indent.
|
||||
bool m_autoIndent;
|
||||
|
||||
// Auto List.
|
||||
bool m_autoList;
|
||||
|
||||
// App defined color
|
||||
QVector<VColor> predefinedColors;
|
||||
QString curBackgroundColor;
|
||||
@ -362,6 +374,36 @@ inline void VConfigManager::setHighlightSearchedWord(bool p_searchedWord)
|
||||
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
|
||||
{
|
||||
return predefinedColors;
|
||||
|
@ -467,6 +467,20 @@ void VMainWindow::initEditMenu()
|
||||
connect(tabStopWidthAct, &QActionGroup::triggered,
|
||||
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.
|
||||
QAction *cursorLineAct = new QAction(tr("Highlight Cursor Line"), this);
|
||||
cursorLineAct->setStatusTip(tr("Highlight current cursor line"));
|
||||
@ -494,11 +508,7 @@ void VMainWindow::initEditMenu()
|
||||
findReplaceMenu->addAction(m_replaceAllAct);
|
||||
findReplaceMenu->addSeparator();
|
||||
findReplaceMenu->addAction(searchedWordAct);
|
||||
if (vconfig.getHighlightSearchedWord()) {
|
||||
searchedWordAct->setChecked(true);
|
||||
} else {
|
||||
searchedWordAct->setChecked(false);
|
||||
}
|
||||
searchedWordAct->setChecked(vconfig.getHighlightSearchedWord());
|
||||
|
||||
editMenu->addSeparator();
|
||||
m_findReplaceAct->setEnabled(false);
|
||||
@ -532,21 +542,26 @@ void VMainWindow::initEditMenu()
|
||||
default:
|
||||
qWarning() << "unsupported tab stop width" << tabStopWidth << "in config";
|
||||
}
|
||||
initEditorBackgroundMenu(editMenu);
|
||||
editMenu->addSeparator();
|
||||
editMenu->addAction(cursorLineAct);
|
||||
if (vconfig.getHighlightCursorLine()) {
|
||||
cursorLineAct->setChecked(true);
|
||||
} else {
|
||||
cursorLineAct->setChecked(false);
|
||||
|
||||
editMenu->addAction(m_autoIndentAct);
|
||||
m_autoIndentAct->setChecked(vconfig.getAutoIndent());
|
||||
|
||||
editMenu->addAction(autoListAct);
|
||||
if (vconfig.getAutoList()) {
|
||||
// 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);
|
||||
if (vconfig.getHighlightSelectedWord()) {
|
||||
selectedWordAct->setChecked(true);
|
||||
} else {
|
||||
selectedWordAct->setChecked(false);
|
||||
}
|
||||
selectedWordAct->setChecked(vconfig.getHighlightSelectedWord());
|
||||
}
|
||||
|
||||
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 enableMathjax(bool p_checked);
|
||||
void handleCaptainModeChanged(bool p_enabled);
|
||||
void changeAutoIndent(bool p_checked);
|
||||
void changeAutoList(bool p_checked);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
||||
@ -148,6 +150,8 @@ private:
|
||||
QAction *m_replaceFindAct;
|
||||
QAction *m_replaceAllAct;
|
||||
|
||||
QAction *m_autoIndentAct;
|
||||
|
||||
// Menus
|
||||
QMenu *viewMenu;
|
||||
|
||||
|
@ -20,6 +20,9 @@
|
||||
#include "vdownloader.h"
|
||||
#include "vfile.h"
|
||||
#include "vmdedit.h"
|
||||
#include "vconfigmanager.h"
|
||||
|
||||
extern VConfigManager vconfig;
|
||||
|
||||
const QString VMdEditOperations::c_defaultImageTitle = "image";
|
||||
|
||||
@ -178,7 +181,25 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
int modifiers = p_event->modifiers();
|
||||
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:
|
||||
{
|
||||
if (handleKeyTab(p_event)) {
|
||||
@ -267,6 +288,14 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Return:
|
||||
{
|
||||
if (handleKeyReturn(p_event)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -612,6 +641,73 @@ bool VMdEditOperations::handleKeyEsc(QKeyEvent *p_event)
|
||||
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)
|
||||
{
|
||||
int modifiers = p_event->modifiers();
|
||||
@ -1004,3 +1100,37 @@ void VMdEditOperations::setKeyState(KeyState p_state)
|
||||
m_keyState = p_state;
|
||||
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 handleKeyW(QKeyEvent *p_event);
|
||||
bool handleKeyEsc(QKeyEvent *p_event);
|
||||
bool handleKeyReturn(QKeyEvent *p_event);
|
||||
bool handleKeyPressVim(QKeyEvent *p_event);
|
||||
bool handleKeyBracketLeft(QKeyEvent *p_event);
|
||||
bool shouldTriggerVimMode(QKeyEvent *p_event);
|
||||
int keySeqToNumber(const QList<QString> &p_seq);
|
||||
bool suffixNumAllowed(const QList<QString> &p_seq);
|
||||
bool insertTitle(int p_level);
|
||||
void insertNewBlockWithIndent();
|
||||
void insertListMarkAsPreviousLine();
|
||||
|
||||
QTimer *m_pendingTimer;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user