diff --git a/src/widgets/krichtextedit.cpp b/src/widgets/krichtextedit.cpp --- a/src/widgets/krichtextedit.cpp +++ b/src/widgets/krichtextedit.cpp @@ -533,9 +533,7 @@ { bool handled = false; if (textCursor().currentList()) { - // handled is False if the key press event was not handled or not completely - // handled by the Helper class. - handled = d->nestedListHelper->handleBeforeKeyPressEvent(event); + handled = d->nestedListHelper->handleKeyPressEvent(event); } // If a line was merged with previous (next) one, with different heading level, @@ -572,9 +570,6 @@ textCursor().endEditBlock(); } - if (textCursor().currentList()) { - d->nestedListHelper->handleAfterKeyPressEvent(event); - } emit cursorPositionChanged(); } diff --git a/src/widgets/nestedlisthelper.cpp b/src/widgets/nestedlisthelper.cpp --- a/src/widgets/nestedlisthelper.cpp +++ b/src/widgets/nestedlisthelper.cpp @@ -31,107 +31,69 @@ NestedListHelper::NestedListHelper(QTextEdit *te) { textEdit = te; - listBottomMargin = 12; - listTopMargin = 12; - listNoMargin = 0; } NestedListHelper::~NestedListHelper() { } -bool NestedListHelper::handleBeforeKeyPressEvent(QKeyEvent *event) +bool NestedListHelper::handleKeyPressEvent(QKeyEvent *event) { QTextCursor cursor = textEdit->textCursor(); - - // Only attempt to handle Backspace while on a list - if ((event->key() != Qt::Key_Backspace) - || (!cursor.currentList())) { + if (!cursor.currentList()) { return false; } - bool handled = false; + if (event->key() == Qt::Key_Backspace && !cursor.hasSelection() && cursor.atBlockStart() && canDedent()) { + handleOnIndentLess(); + return true; + } - if (!cursor.hasSelection() - && cursor.currentList() - && event->key() == Qt::Key_Backspace - && cursor.atBlockStart()) { + if (event->key() == Qt::Key_Return && !cursor.hasSelection() && cursor.block().text().isEmpty() && canDedent()) { handleOnIndentLess(); - handled = true; + return true; } - return handled; + if (event->key() == Qt::Key_Tab && (cursor.atBlockStart() || cursor.hasSelection()) && canIndent()) { + handleOnIndentMore(); + return true; + } + + return false; } bool NestedListHelper::canIndent() const { - if ((textEdit->textCursor().block().isValid()) -// && ( textEdit->textCursor().block().previous().isValid() ) - ) { - QTextBlock block = textEdit->textCursor().block(); - QTextBlock prevBlock = textEdit->textCursor().block().previous(); - if (block.textList()) { - if (prevBlock.textList()) { - return block.textList()->format().indent() <= prevBlock.textList()->format().indent(); - } - } else { - return true; - } + QTextCursor cursor = topOfSelection(); + QTextBlock block = cursor.block(); + QTextBlock prevBlock = block.previous(); + if (!block.isValid()) { + return false; } - return false; + if (!block.textList()) { + return true; + } + if (!prevBlock.textList()) { + return false; + } + return block.textList()->format().indent() <= prevBlock.textList()->format().indent(); } bool NestedListHelper::canDedent() const { - QTextBlock thisBlock = textEdit->textCursor().block(); - QTextBlock nextBlock = thisBlock.next(); - if (thisBlock.isValid()) { - int nextBlockIndent = 0; - if (nextBlock.isValid() && nextBlock.textList()) { - nextBlockIndent = nextBlock.textList()->format().indent(); - } - if (thisBlock.textList()) { - const int thisBlockIndent = thisBlock.textList()->format().indent(); - if (thisBlockIndent >= nextBlockIndent) { - return thisBlock.textList()->format().indent() > 0; - } - } + QTextCursor cursor = bottomOfSelection(); + QTextBlock block = cursor.block(); + QTextBlock nextBlock = block.next(); + if (!block.isValid()) { + return false; } - return false; - -} - -bool NestedListHelper::handleAfterKeyPressEvent(QKeyEvent *event) -{ - // Only attempt to handle Backspace and Return - if ((event->key() != Qt::Key_Backspace) - && (event->key() != Qt::Key_Return)) { + if (!block.textList() || block.textList()->format().indent() <= 0) { return false; } - - QTextCursor cursor = textEdit->textCursor(); - bool handled = false; - - if (!cursor.hasSelection() && cursor.currentList()) { - - // Check if we're on the last list item. - // itemNumber is zero indexed - QTextBlock currentBlock = cursor.block(); - if (cursor.currentList()->count() == cursor.currentList()->itemNumber(currentBlock) + 1) { - // Last block in this list, but may have just gained another list below. - if (currentBlock.next().textList()) { - reformatList(); - } - - // No need to reformatList in this case. reformatList is slow. - if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Backspace)) { - handled = true; - } - } else { - reformatList(); - } + if (!nextBlock.textList()) { + return true; } - return handled; + return block.textList()->format().indent() >= nextBlock.textList()->format().indent(); } bool NestedListHelper::handleAfterDropEvent(QDropEvent *dropEvent) @@ -219,7 +181,7 @@ reformatList(cursor.block()); } -QTextCursor NestedListHelper::topOfSelection() +QTextCursor NestedListHelper::topOfSelection() const { QTextCursor cursor = textEdit->textCursor(); @@ -229,7 +191,7 @@ return cursor; } -QTextCursor NestedListHelper::bottomOfSelection() +QTextCursor NestedListHelper::bottomOfSelection() const { QTextCursor cursor = textEdit->textCursor(); @@ -242,6 +204,7 @@ void NestedListHelper::handleOnIndentMore() { QTextCursor cursor = textEdit->textCursor(); + cursor.beginEditBlock(); QTextListFormat listFmt; if (!cursor.currentList()) { @@ -270,6 +233,7 @@ cursor.createList(listFmt); reformatList(); } + cursor.endEditBlock(); } void NestedListHelper::handleOnIndentLess() @@ -279,6 +243,7 @@ if (!currentList) { return; } + cursor.beginEditBlock(); QTextListFormat listFmt; listFmt = currentList->format(); if (listFmt.indent() > 1) { @@ -291,6 +256,7 @@ cursor.setBlockFormat(bfmt); reformatList(cursor.block().next()); } + cursor.endEditBlock(); } void NestedListHelper::handleOnBulletType(int styleIndex) diff --git a/src/widgets/nestedlisthelper_p.h b/src/widgets/nestedlisthelper_p.h --- a/src/widgets/nestedlisthelper_p.h +++ b/src/widgets/nestedlisthelper_p.h @@ -61,26 +61,16 @@ * * Handles a key press before it is processed by the text edit widget. * - * Currently this causes a backspace at the beginning of a line or with a - * multi-line selection to decrease the nesting level of the list. + * This includes: + * 1. Backspace at the beginning of a line decreases nesting level + * 2. Return at the empty list element decreases nesting level + * 3. Tab at the beginning of a line OR with a multi-line selection + * increases nesting level * * @param event The event to be handled * @return Whether the event was completely handled by this method. */ - bool handleBeforeKeyPressEvent(QKeyEvent *event); - - /** - * - * Handles a key press after it is processed by the text edit widget. - * - * Currently this causes a Return at the end of the last list item, or - * a Backspace after the last list item to recalculate the spacing - * between the list items. - * - * @param event The event to be handled - * @return Whether the event was completely handled by this method. - */ - bool handleAfterKeyPressEvent(QKeyEvent *event); + bool handleKeyPressEvent(QKeyEvent *event); bool handleAfterDropEvent(QDropEvent *event); @@ -119,27 +109,23 @@ /** * \brief Check whether the current item in the list may be dedented. * - * An item may be dedented if it is part of a list. Otherwise it can't be. + * An item may be dedented if it is part of a list. + * The next item must be at the same or lesser level. * * @sa canIndent * * @return Whether the item can be dedented. */ bool canDedent() const; private: - QTextCursor topOfSelection(); - QTextCursor bottomOfSelection(); + QTextCursor topOfSelection() const; + QTextCursor bottomOfSelection() const; void processList(QTextList *list); void reformatList(QTextBlock block); void reformatList(); QTextEdit *textEdit = nullptr; - - int listBottomMargin; - int listTopMargin; - int listNoMargin; - }; //@endcond