From a71436649c2ec4bdd3732ee81cacd4165b1d8c00 Mon Sep 17 00:00:00 2001 From: mae <qt-info@nokia.com> Date: Thu, 23 Apr 2009 17:28:53 +0200 Subject: [PATCH] removed the folding ribbon from the default configuration, instead turned a new block highlighting mechanism on. --- src/plugins/texteditor/basetexteditor.cpp | 141 ++++++++++++++++++--- src/plugins/texteditor/basetexteditor.h | 4 + src/plugins/texteditor/basetexteditor_p.h | 16 +++ src/plugins/texteditor/displaysettings.cpp | 8 +- 4 files changed, 150 insertions(+), 19 deletions(-) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 9724ccf0b7f..081d343764a 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -188,6 +188,10 @@ BaseTextEditor::BaseTextEditor(QWidget *parent) d->m_parenthesesMatchingTimer->setSingleShot(true); connect(d->m_parenthesesMatchingTimer, SIGNAL(timeout()), this, SLOT(_q_matchParentheses())); + d->m_highlightBlocksTimer = new QTimer(this); + d->m_highlightBlocksTimer->setSingleShot(true); + connect(d->m_highlightBlocksTimer, SIGNAL(timeout()), this, SLOT(_q_highlightBlocks())); + d->m_searchResultFormat.setBackground(QColor(0xffef0b)); @@ -429,6 +433,23 @@ bool DocumentMarker::addMark(TextEditor::ITextMark *mark, int line) return false; } +int BaseTextEditorPrivate::visualIndent(const QTextBlock &block) const +{ + if (!block.isValid()) + return 0; + const QTextDocument *document = block.document(); + int i = 0; + while (i < block.length()) { + if (!document->characterAt(block.position() + i).isSpace()) { + QTextCursor cursor(block); + cursor.setPosition(block.position() + i); + return q->cursorRect(cursor).x(); + } + ++i; + } + + return 0; +} TextEditor::TextMarks DocumentMarker::marksAt(int line) const { @@ -1198,8 +1219,11 @@ bool BaseTextEditor::lineSeparatorsAllowed() const void BaseTextEditor::setHighlightBlocks(bool b) { - d->m_highlightBlocks = b & d->m_codeFoldingSupported; - viewport()->update(); + if (d->m_highlightBlocks == b) + return; + d->m_highlightBlocks = b; + d->m_highlightBlocksInfo = BaseTextEditorPrivateHighlightBlocks(); + _q_highlightBlocks(); } bool BaseTextEditor::highlightBlocks() const @@ -1755,22 +1779,28 @@ void BaseTextEditor::paintEvent(QPaintEvent *e) QTextBlock visibleCollapsedBlock; QPointF visibleCollapsedBlockOffset; + + while (block.isValid()) { QRectF r = blockBoundingRect(block).translated(offset); if (d->m_highlightBlocks) { - QTextBlock previousBlock = block.previous(); - if (previousBlock.isValid()){ - int thisBraceDepth = block.userState(); - if (thisBraceDepth >= 0) - thisBraceDepth >>= 8; - int braceDepth = block.previous().userState(); - if (braceDepth >= 0) - braceDepth >>= 8; - int minBraceDepth = qMin(thisBraceDepth, braceDepth); - if (minBraceDepth > 0) { - painter.fillRect(r, calcBlendColor(baseColor, minBraceDepth)); + + int n = block.blockNumber(); + int depth = 0; + foreach (int i, d->m_highlightBlocksInfo.open) + if (n >= i) + ++depth; + foreach (int i, d->m_highlightBlocksInfo.close) + if (n > i) + --depth; + + int count = d->m_highlightBlocksInfo.visualIndent.size(); + if (count) { + for(int i = 0; i <= depth; ++i) { + int vi = i > 0 ? d->m_highlightBlocksInfo.visualIndent.at(i-1) : 0; + painter.fillRect(r.adjusted(vi, 0, 0, 0), calcBlendColor(baseColor, count - i)); } } } @@ -1814,7 +1844,7 @@ void BaseTextEditor::paintEvent(QPaintEvent *e) else selections.append(o); } else if (!range.cursor.hasSelection() && range.format.hasProperty(QTextFormat::FullWidthSelection) - && block.contains(range.cursor.position())) { + && block.contains(range.cursor.position())) { // for full width selections we don't require an actual selection, just // a position to specify the line. that's more convenience in usage. QTextLayout::FormatRange o; @@ -1881,7 +1911,6 @@ void BaseTextEditor::paintEvent(QPaintEvent *e) // invisible blocks do have zero line count block = doc->findBlockByLineNumber(block.firstLineNumber()); } - } if (backgroundVisible() && !block.isValid() && offset.y() <= er.bottom() @@ -2390,6 +2419,10 @@ void BaseTextEditor::slotCursorPositionChanged() } setExtraSelections(CurrentLineSelection, extraSelections); + + if (d->m_highlightBlocks) { + d->m_highlightBlocksTimer->start(100); + } } void BaseTextEditor::slotUpdateBlockNotify(const QTextBlock &block) @@ -3139,6 +3172,67 @@ bool TextBlockUserData::findNextClosingParenthesis(QTextCursor *cursor, bool sel return false; } +bool TextBlockUserData::findPreviousBlockOpenParenthesis(QTextCursor *cursor) +{ + QTextBlock block = cursor->block(); + int position = cursor->position(); + int ignore = 0; + while (block.isValid()) { + Parentheses parenList = TextEditDocumentLayout::parentheses(block); + if (!parenList.isEmpty() && !TextEditDocumentLayout::ifdefedOut(block)) { + for (int i = parenList.count()-1; i >= 0; --i) { + Parenthesis paren = parenList.at(i); + if (paren.chr != QLatin1Char('{') && paren.chr != QLatin1Char('}') + && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) + continue; + if (block == cursor->block() && + (position - block.position() <= paren.pos)) + continue; + if (paren.type == Parenthesis::Closed) { + ++ignore; + } else if (ignore > 0) { + --ignore; + } else { + cursor->setPosition(block.position() + paren.pos); + return true; + } + } + } + block = block.previous(); + } + return false; +} + +bool TextBlockUserData::findNextBlockClosingParenthesis(QTextCursor *cursor) +{ + QTextBlock block = cursor->block(); + int position = cursor->position(); + int ignore = 0; + while (block.isValid()) { + Parentheses parenList = TextEditDocumentLayout::parentheses(block); + if (!parenList.isEmpty() && !TextEditDocumentLayout::ifdefedOut(block)) { + for (int i = 0; i < parenList.count(); ++i) { + Parenthesis paren = parenList.at(i); + if (paren.chr != QLatin1Char('{') && paren.chr != QLatin1Char('}') + && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) + continue; + if (block == cursor->block() && position - block.position() >= paren.pos) + continue; + if (paren.type == Parenthesis::Opened) { + ++ignore; + } else if (ignore > 0) { + --ignore; + } else { + cursor->setPosition(block.position() + paren.pos+1); + return true; + } + } + } + block = block.next(); + } + return false; +} + TextBlockUserData::MatchType TextBlockUserData::matchCursorBackward(QTextCursor *cursor) { cursor->clearSelection(); @@ -3274,6 +3368,23 @@ void BaseTextEditor::_q_matchParentheses() setExtraSelections(ParenthesesMatchingSelection, extraSelections); } +void BaseTextEditor::_q_highlightBlocks() +{ + QTextCursor cursor = textCursor(); + QTextCursor closeCursor = cursor; + BaseTextEditorPrivateHighlightBlocks highlightBlocksInfo; + while (TextBlockUserData::findPreviousBlockOpenParenthesis(&cursor)) { + highlightBlocksInfo.open.prepend(cursor.blockNumber()); + highlightBlocksInfo.visualIndent.prepend(d->visualIndent(cursor.block())); + if (TextBlockUserData::findNextBlockClosingParenthesis(&closeCursor)) + highlightBlocksInfo.close.append(closeCursor.blockNumber()); + } + if (d->m_highlightBlocksInfo != highlightBlocksInfo) { + d->m_highlightBlocksInfo = highlightBlocksInfo; + viewport()->update(); + } +} + void BaseTextEditor::setActionHack(QObject *hack) { d->m_actionHack = hack; diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 19ce6b36799..f0669a71046 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -167,6 +167,9 @@ public: static bool findPreviousOpenParenthesis(QTextCursor *cursor, bool select = false); static bool findNextClosingParenthesis(QTextCursor *cursor, bool select = false); + static bool findPreviousBlockOpenParenthesis(QTextCursor *cursor); + static bool findNextBlockClosingParenthesis(QTextCursor *cursor); + private: TextMarks m_marks; @@ -464,6 +467,7 @@ private: // parentheses matcher private slots: void _q_matchParentheses(); + void _q_highlightBlocks(); void slotSelectionChanged(); }; diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 74f158dab5e..9bff3da0f41 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -114,6 +114,17 @@ private: //================BaseTextEditorPrivate============== +struct BaseTextEditorPrivateHighlightBlocks +{ + QList<int> open; + QList<int> close; + QList<int> visualIndent; + inline bool operator==(const BaseTextEditorPrivateHighlightBlocks &o) const { + return (open == o.open && close == o.close && visualIndent == o.visualIndent); + } + inline bool operator!=(const BaseTextEditorPrivateHighlightBlocks &o) const { return !(*this == o); } +}; + class BaseTextEditorPrivate { BaseTextEditorPrivate(const BaseTextEditorPrivate &); @@ -219,6 +230,11 @@ public: QTextCursor m_selectBlockAnchor; void moveCursorVisible(bool ensureVisible = true); + + int visualIndent(const QTextBlock &block) const; + BaseTextEditorPrivateHighlightBlocks m_highlightBlocksInfo; + QTimer *m_highlightBlocksTimer; + }; } // namespace Internal diff --git a/src/plugins/texteditor/displaysettings.cpp b/src/plugins/texteditor/displaysettings.cpp index 47e9ad4d474..27480d3dcc5 100644 --- a/src/plugins/texteditor/displaysettings.cpp +++ b/src/plugins/texteditor/displaysettings.cpp @@ -39,9 +39,9 @@ static const char * const textWrappingKey = "TextWrapping"; static const char * const showWrapColumnKey = "ShowWrapColumn"; static const char * const wrapColumnKey = "WrapColumn"; static const char * const visualizeWhitespaceKey = "VisualizeWhitespace"; -static const char * const displayFoldingMarkersKey = "DisplayFoldingMarkers"; +static const char * const displayFoldingMarkersKey = "DisplayFoldingMarkersV2"; static const char * const highlightCurrentLineKey = "HighlightCurrentLineKey"; -static const char * const highlightBlocksKey = "HighlightBlocksKey"; +static const char * const highlightBlocksKey = "HighlightBlocksKeyV2"; static const char * const groupPostfix = "DisplaySettings"; namespace TextEditor { @@ -52,9 +52,9 @@ DisplaySettings::DisplaySettings() : m_showWrapColumn(false), m_wrapColumn(80), m_visualizeWhitespace(false), - m_displayFoldingMarkers(true), + m_displayFoldingMarkers(false), m_highlightCurrentLine(true), - m_highlightBlocks(false) + m_highlightBlocks(true) { } -- GitLab