diff --git a/src/utils/veditutils.cpp b/src/utils/veditutils.cpp index 5152e855..ace042df 100644 --- a/src/utils/veditutils.cpp +++ b/src/utils/veditutils.cpp @@ -689,3 +689,49 @@ bool VEditUtils::needToCancelAutoIndent(int p_autoIndentPos, const QTextCursor & return false; } + +void VEditUtils::insertTitleMark(QTextCursor &p_cursor, + const QTextBlock &p_block, + int p_level) +{ + if (!p_block.isValid()) { + return; + } + + Q_ASSERT(p_level >= 1 && p_level <= 6); + + bool needInsert = true; + + p_cursor.setPosition(p_block.position()); + + // Test if this block contains title marks. + QRegExp headerReg(VUtils::c_headerRegExp); + QString text = p_block.text(); + bool matched = headerReg.exactMatch(text); + if (matched) { + int level = headerReg.cap(1).length(); + if (level == p_level) { + needInsert = false; + } else { + // Remove the title mark. + p_cursor.movePosition(QTextCursor::NextCharacter, + QTextCursor::KeepAnchor, + level); + p_cursor.removeSelectedText(); + } + } + + // Insert titleMark + " " at the front of the block. + if (needInsert) { + // Remove the spaces at front. + // insertText() will remove the selection. + moveCursorFirstNonSpaceCharacter(p_cursor, QTextCursor::KeepAnchor); + + // Insert. + const QString titleMark(p_level, '#'); + p_cursor.insertText(titleMark + " "); + } + + // Go to the end of this block. + p_cursor.movePosition(QTextCursor::EndOfBlock); +} diff --git a/src/utils/veditutils.h b/src/utils/veditutils.h index bae56cca..62d9f930 100644 --- a/src/utils/veditutils.h +++ b/src/utils/veditutils.h @@ -132,7 +132,15 @@ public: // Check if we need to cancel auto indent. // @p_autoIndentPos: the position of the cursor after auto indent. - static bool needToCancelAutoIndent(int p_autoIndentPos, const QTextCursor &p_cursor); + static bool needToCancelAutoIndent(int p_autoIndentPos, + const QTextCursor &p_cursor); + + // 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. + static void insertTitleMark(QTextCursor &p_cursor, + const QTextBlock &p_block, + int p_level); private: VEditUtils() {} diff --git a/src/vmdeditoperations.cpp b/src/vmdeditoperations.cpp index bb80e883..9dbd0079 100644 --- a/src/vmdeditoperations.cpp +++ b/src/vmdeditoperations.cpp @@ -626,33 +626,25 @@ void VMdEditOperations::changeListBlockSeqNumber(QTextBlock &p_block, int p_seq) 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(); + int firstBlock = cursor.block().blockNumber(); + int lastBlock = firstBlock; + if (cursor.hasSelection()) { - // Insert title # in front of the selected lines. + // Insert title # in front of the selected blocks. 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(); + firstBlock = doc->findBlock(start).blockNumber(); + lastBlock = doc->findBlock(end).blockNumber(); } + + cursor.beginEditBlock(); + for (int i = firstBlock; i <= lastBlock; ++i) { + VEditUtils::insertTitleMark(cursor, doc->findBlockByNumber(i), p_level); + } + + cursor.endEditBlock(); m_editor->setTextCursor(cursor); return true; } diff --git a/src/vmdeditoperations.h b/src/vmdeditoperations.h index faeb791f..57478328 100644 --- a/src/vmdeditoperations.h +++ b/src/vmdeditoperations.h @@ -47,6 +47,10 @@ private: bool handleKeyEsc(QKeyEvent *p_event); bool handleKeyReturn(QKeyEvent *p_event); bool handleKeyBracketLeft(QKeyEvent *p_event); + + // 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. bool insertTitle(int p_level); // Change the sequence number of a list block. diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp index cfa605bd..f3cd018b 100644 --- a/src/vmdtab.cpp +++ b/src/vmdtab.cpp @@ -286,7 +286,7 @@ bool VMdTab::saveFile() return true; } - bool ret; + bool ret = true; // Make sure the file already exists. Temporary deal with cases when user delete or move // a file. QString filePath = m_file->fetchPath(); @@ -296,17 +296,19 @@ bool VMdTab::saveFile() tr("File %2 being written has been removed.") .arg(g_config->c_dataTextStyle).arg(filePath), QMessageBox::Ok, QMessageBox::Ok, this); - return false; + ret = false; + } else { + m_editor->saveFile(); + ret = m_file->save(); + if (!ret) { + VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), + tr("Fail to write to disk when saving a note. Please try it again."), + QMessageBox::Ok, QMessageBox::Ok, this); + m_editor->setModified(true); + } } - m_editor->saveFile(); - ret = m_file->save(); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), - tr("Fail to write to disk when saving a note. Please try it again."), - QMessageBox::Ok, QMessageBox::Ok, this); - m_editor->setModified(true); - } + updateStatus(); return ret; }