mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
refactor edit operations
- Ctrl+B/I/K/D/M: Revert if content between the markers is empty. - Ctrl+7: delete title mark.
This commit is contained in:
parent
ce48cdafd6
commit
1f0ee88770
@ -17,6 +17,8 @@ VNote supports `Ctrl+J` and `Ctrl+K` for navigation in the notebooks list, direc
|
||||
Scroll in all directions.
|
||||
- `Ctrl+Shift+T`
|
||||
Recover last closed file.
|
||||
- `Ctrl+Alt+L`
|
||||
Open Flash Page.
|
||||
|
||||
### Read Mode
|
||||
- `Ctrl+W`
|
||||
@ -70,6 +72,8 @@ Delete all the characters from current cursor to the first space backward.
|
||||
Delete all the characters from current cursor to the beginning of current line.
|
||||
- `Ctrl+<Num>`
|
||||
Insert title at level `<Num>`. `<Num>` should be 1 to 6. Current selected text will be changed to title if exists.
|
||||
- `Ctrl+7`
|
||||
Delete the title mark of current line or selected text.
|
||||
- `Tab`/`Shift+Tab`
|
||||
Increase or decrease the indentation. If any text is selected, the indentation will operate on all these selected lines.
|
||||
- `Shift+Enter`
|
||||
|
@ -17,6 +17,8 @@
|
||||
任意滚动。
|
||||
- `Ctrl+Shift+T`
|
||||
恢复上一个关闭的文件。
|
||||
- `Ctrl+Alt+L`
|
||||
打开灵犀页。
|
||||
|
||||
### 阅读模式
|
||||
- `Ctrl+W`
|
||||
@ -70,6 +72,8 @@
|
||||
删除光标位置到行首的所有字符。
|
||||
- `Ctrl+<Num>`
|
||||
插入级别为`<Num>`的标题。`<Num>`应该是1到6的一个数字。如果已经选择文本,则将当前选择文本改为标题。
|
||||
- `Ctrl+7`
|
||||
删除当前行或所选择文本的标题标记。
|
||||
- `Tab`/`Shift+Tab`
|
||||
增加或减小缩进。如果已经选择文本,则对所有选择的行进行缩进操作。
|
||||
- `Shift+Enter`
|
||||
|
@ -785,7 +785,7 @@ void VEditUtils::insertTitleMark(QTextCursor &p_cursor,
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT(p_level >= 1 && p_level <= 6);
|
||||
Q_ASSERT(p_level >= 0 && p_level <= 6);
|
||||
|
||||
bool needInsert = true;
|
||||
|
||||
@ -801,15 +801,24 @@ void VEditUtils::insertTitleMark(QTextCursor &p_cursor,
|
||||
needInsert = false;
|
||||
} else {
|
||||
// Remove the title mark.
|
||||
int length = level;
|
||||
if (p_level == 0) {
|
||||
// Remove all the prefix.
|
||||
QRegExp prefixReg(VUtils::c_headerPrefixRegExp);
|
||||
bool preMatched = prefixReg.exactMatch(text);
|
||||
Q_ASSERT(preMatched);
|
||||
length = prefixReg.cap(1).length();
|
||||
}
|
||||
|
||||
p_cursor.movePosition(QTextCursor::NextCharacter,
|
||||
QTextCursor::KeepAnchor,
|
||||
level);
|
||||
length);
|
||||
p_cursor.removeSelectedText();
|
||||
}
|
||||
}
|
||||
|
||||
// Insert titleMark + " " at the front of the block.
|
||||
if (needInsert) {
|
||||
if (p_level > 0 && needInsert) {
|
||||
// Remove the spaces at front.
|
||||
// insertText() will remove the selection.
|
||||
moveCursorFirstNonSpaceCharacter(p_cursor, QTextCursor::KeepAnchor);
|
||||
|
@ -151,6 +151,7 @@ public:
|
||||
// Insert title Mark at level @p_level in front of block @p_block
|
||||
// If there already exists title marks, remove it first.
|
||||
// Move cursor at the end of the block after insertion.
|
||||
// If @p_level is 0, remove the title mark.
|
||||
static void insertTitleMark(QTextCursor &p_cursor,
|
||||
const QTextBlock &p_block,
|
||||
int p_level);
|
||||
|
@ -219,10 +219,11 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
||||
case Qt::Key_4:
|
||||
case Qt::Key_5:
|
||||
case Qt::Key_6:
|
||||
case Qt::Key_7:
|
||||
{
|
||||
if (modifiers == Qt::ControlModifier) {
|
||||
// Ctrl + <N>: insert title at level <N>.
|
||||
if (insertTitle(key - Qt::Key_0)) {
|
||||
if (insertTitle(key == Qt::Key_7 ? 0 : key - Qt::Key_0)) {
|
||||
p_event->accept();
|
||||
ret = true;
|
||||
goto exit;
|
||||
@ -728,18 +729,32 @@ void VMdEditOperations::decorateBold()
|
||||
cursor.insertText("**");
|
||||
} else {
|
||||
// Insert **** and place cursor in the middle.
|
||||
// Or if there are two * after current cursor, just skip them.
|
||||
// Or if there are two * after current cursor, just skip them or delete
|
||||
// them if four * appear.
|
||||
int pos = cursor.positionInBlock();
|
||||
bool hasStars = false;
|
||||
bool emptyMarkers = false;
|
||||
QString text = cursor.block().text();
|
||||
if (pos <= text.size() - 2) {
|
||||
if (text[pos] == '*' && text[pos + 1] == '*') {
|
||||
hasStars = true;
|
||||
|
||||
if (pos >= 2
|
||||
&& text[pos - 1] == '*'
|
||||
&& text[pos - 2] == '*') {
|
||||
emptyMarkers = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasStars) {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
|
||||
if (emptyMarkers) {
|
||||
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 2);
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4);
|
||||
cursor.removeSelectedText();
|
||||
} else {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
|
||||
}
|
||||
} else {
|
||||
cursor.insertText("****");
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
|
||||
@ -765,18 +780,31 @@ void VMdEditOperations::decorateItalic()
|
||||
cursor.insertText("*");
|
||||
} else {
|
||||
// Insert ** and place cursor in the middle.
|
||||
// Or if there are one * after current cursor, just skip it.
|
||||
// Or if there are one * after current cursor, just skip them or delete
|
||||
// them if two * appear.
|
||||
int pos = cursor.positionInBlock();
|
||||
bool hasStar = false;
|
||||
bool emptyMarkers = false;
|
||||
QString text = cursor.block().text();
|
||||
if (pos <= text.size() - 1) {
|
||||
if (text[pos] == '*') {
|
||||
if (text[pos] == '*'
|
||||
&& (pos == text.size() - 1 || text[pos + 1] != '*')) {
|
||||
hasStar = true;
|
||||
|
||||
if (pos >= 1 && text[pos - 1] == '*') {
|
||||
emptyMarkers = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasStar) {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
||||
if (emptyMarkers) {
|
||||
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 1);
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
|
||||
cursor.removeSelectedText();
|
||||
} else {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
||||
}
|
||||
} else {
|
||||
cursor.insertText("**");
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||
@ -802,18 +830,30 @@ void VMdEditOperations::decorateInlineCode()
|
||||
cursor.insertText("`");
|
||||
} else {
|
||||
// Insert `` and place cursor in the middle.
|
||||
// Or if there are one ` after current cursor, just skip it.
|
||||
// Or if there are one ` after current cursor, just skip them or delete
|
||||
// them if two ` appear.
|
||||
int pos = cursor.positionInBlock();
|
||||
bool hasBackquote = false;
|
||||
bool emptyMarkers = false;
|
||||
QString text = cursor.block().text();
|
||||
if (pos <= text.size() - 1) {
|
||||
if (text[pos] == '`') {
|
||||
hasBackquote = true;
|
||||
|
||||
if (pos >= 1 && text[pos - 1] == '`') {
|
||||
emptyMarkers = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasBackquote) {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
||||
if (emptyMarkers) {
|
||||
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 1);
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
|
||||
cursor.removeSelectedText();
|
||||
} else {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
||||
}
|
||||
} else {
|
||||
cursor.insertText("``");
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||
@ -857,22 +897,32 @@ void VMdEditOperations::decorateCodeBlock()
|
||||
|| state == HighlightBlockState::CodeBlockStart
|
||||
|| state == HighlightBlockState::CodeBlockEnd) {
|
||||
// Find the block end.
|
||||
while (block.isValid()) {
|
||||
if (block.userState() == HighlightBlockState::CodeBlockEnd) {
|
||||
QTextBlock endBlock = block;
|
||||
while (endBlock.isValid()) {
|
||||
if (endBlock.userState() == HighlightBlockState::CodeBlockEnd) {
|
||||
break;
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
endBlock = endBlock.next();
|
||||
}
|
||||
|
||||
if (block.isValid()) {
|
||||
if (endBlock.isValid()) {
|
||||
// It is CodeBlockEnd.
|
||||
cursor.setPosition(block.position());
|
||||
if (block.next().isValid()) {
|
||||
cursor.movePosition(QTextCursor::NextBlock);
|
||||
cursor.movePosition(QTextCursor::StartOfBlock);
|
||||
if (endBlock.previous().isValid()
|
||||
&& endBlock.previous().userState() == HighlightBlockState::CodeBlockStart) {
|
||||
// Delete empty code blocks.
|
||||
cursor.setPosition(endBlock.previous().position());
|
||||
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
|
||||
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||
cursor.removeSelectedText();
|
||||
} else {
|
||||
cursor.movePosition(QTextCursor::EndOfBlock);
|
||||
cursor.setPosition(endBlock.position());
|
||||
if (endBlock.next().isValid()) {
|
||||
cursor.movePosition(QTextCursor::NextBlock);
|
||||
cursor.movePosition(QTextCursor::StartOfBlock);
|
||||
} else {
|
||||
cursor.movePosition(QTextCursor::EndOfBlock);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Reach the end of the document.
|
||||
@ -919,18 +969,32 @@ void VMdEditOperations::decorateStrikethrough()
|
||||
cursor.insertText("~~");
|
||||
} else {
|
||||
// Insert ~~~~ and place cursor in the middle.
|
||||
// Or if there are one ~~ after current cursor, just skip it.
|
||||
// Or if there are one ~~ after current cursor, just skip it or delete
|
||||
// it if for ~ appear.
|
||||
int pos = cursor.positionInBlock();
|
||||
bool hasStrikethrough = false;
|
||||
bool emptyMarkers = false;
|
||||
QString text = cursor.block().text();
|
||||
if (pos <= text.size() - 2) {
|
||||
if (text[pos] == '~' && text[pos + 1] == '~') {
|
||||
hasStrikethrough = true;
|
||||
|
||||
if (pos >= 2
|
||||
&& text[pos - 1] == '~'
|
||||
&& text[pos - 2] == '~') {
|
||||
emptyMarkers = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasStrikethrough) {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
|
||||
if (emptyMarkers) {
|
||||
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 2);
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4);
|
||||
cursor.removeSelectedText();
|
||||
} else {
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
|
||||
}
|
||||
} else {
|
||||
cursor.insertText("~~~~");
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
|
||||
|
@ -58,6 +58,7 @@ private:
|
||||
// Insert title of level @p_level.
|
||||
// Will detect if current block already has some leading #s. If yes,
|
||||
// will delete it and insert the correct #s.
|
||||
// @p_level: 0 to cancel title.
|
||||
bool insertTitle(int p_level);
|
||||
|
||||
// Change the sequence number of a list block.
|
||||
|
Loading…
x
Reference in New Issue
Block a user