diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp index 03a4701b2102b3a331b0136345a71c80019cbc0e..ed5d82d2796c960400be35cb75197864e5a65f0c 100644 --- a/src/plugins/cppeditor/cpphighlighter.cpp +++ b/src/plugins/cppeditor/cpphighlighter.cpp @@ -52,12 +52,13 @@ void CppHighlighter::highlightBlock(const QString &text) QTextCharFormat emptyFormat; const int previousState = previousBlockState(); - int state = 0, braceDepth = 0; + int state = 0, initialBraceDepth = 0; if (previousState != -1) { state = previousState & 0xff; - braceDepth = previousState >> 8; + initialBraceDepth = previousState >> 8; } + int braceDepth = initialBraceDepth; SimpleLexer tokenize; tokenize.setQtMocRunEnabled(false); @@ -211,6 +212,10 @@ void CppHighlighter::highlightBlock(const QString &text) TextEditDocumentLayout::setParentheses(currentBlock(), parentheses); + // if the block is ifdefed out, we only store the parentheses, but + // do not adjust the brace depth. + if (TextEditDocumentLayout::ifdefedOut(currentBlock())) + braceDepth = initialBraceDepth; // optimization: if only the brace depth changes, we adjust subsequent blocks // to have QSyntaxHighlighter stop the rehighlighting @@ -222,12 +227,7 @@ void CppHighlighter::highlightBlock(const QString &text) int delta = braceDepth - oldBraceDepth; QTextBlock block = currentBlock().next(); while (block.isValid()) { - currentState = block.userState(); - if (currentState != -1) { - oldState = currentState & 0xff; - oldBraceDepth = currentState >> 8; - block.setUserState(((oldBraceDepth + delta) << 8 ) | oldState); - } + TextEditDocumentLayout::changeBraceDepth(block, delta); block = block.next(); } } diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 6592506d57b6751989fcb1a6a366e8e97b69c13f..c38f4df4334d67a07187dffa677504eacb99d8fa 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1528,6 +1528,18 @@ int TextBlockUserData::collapseAtPos() const return Parenthesis::collapseAtPos(m_parentheses); } +int TextBlockUserData::braceDepthDelta() const +{ + int delta = 0; + for (int i = 0; i < m_parentheses.size(); ++i) { + switch (m_parentheses.at(i).chr.unicode()) { + case '{': case '+': ++delta; break; + case '}': case '-': --delta; break; + default: break; + } + } + return delta; +} void TextEditDocumentLayout::setParentheses(const QTextBlock &block, const Parentheses &parentheses) { @@ -1553,6 +1565,35 @@ bool TextEditDocumentLayout::hasParentheses(const QTextBlock &block) return false; } +int TextEditDocumentLayout::braceDepthDelta(const QTextBlock &block) +{ + if (TextBlockUserData *userData = testUserData(block)) + return userData->braceDepthDelta(); + return 0; +} + +int TextEditDocumentLayout::braceDepth(const QTextBlock &block) +{ + int state = block.userState(); + if (state == -1) + return 0; + return state >> 8; +} + +void TextEditDocumentLayout::setBraceDepth(QTextBlock &block, int depth) +{ + int state = block.userState(); + if (state == -1) + state = 0; + state = state & 0xff; + block.setUserState((depth << 8) | state); +} + +void TextEditDocumentLayout::changeBraceDepth(QTextBlock &block, int delta) +{ + if (delta) + setBraceDepth(block, braceDepth(block) + delta); +} bool TextEditDocumentLayout::setIfdefedOut(const QTextBlock &block) { @@ -2683,6 +2724,11 @@ void BaseTextEditor::updateCurrentLineHighlight() void BaseTextEditor::slotCursorPositionChanged() { +#if 0 + qDebug() << "block" << textCursor().blockNumber()+1 + << "depth:" << TextEditDocumentLayout::braceDepth(textCursor().block()) + << "/" << TextEditDocumentLayout::braceDepth(document()->lastBlock()); +#endif if (!d->m_contentsChanged && d->m_lastCursorChangeWasInteresting) { Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(editableInterface(), d->m_tempNavigationState); d->m_lastCursorChangeWasInteresting = false; @@ -4026,21 +4072,36 @@ void BaseTextEditor::setIfdefedOutBlocks(const QList<BaseTextEditor::BlockRange> QTextBlock block = doc->firstBlock(); int rangeNumber = 0; + int braceDepthDelta = 0; while (block.isValid()) { + bool cleared = false; + bool set = false; if (rangeNumber < blocks.size()) { const BlockRange &range = blocks.at(rangeNumber); if (block.position() >= range.first && (block.position() <= range.last || !range.last)) { - needUpdate |= TextEditDocumentLayout::setIfdefedOut(block); + set = TextEditDocumentLayout::setIfdefedOut(block); } else { - needUpdate |= TextEditDocumentLayout::clearIfdefedOut(block); + cleared = TextEditDocumentLayout::clearIfdefedOut(block); } if (block.contains(range.last)) ++rangeNumber; } else { - needUpdate |= TextEditDocumentLayout::clearIfdefedOut(block); + cleared = TextEditDocumentLayout::clearIfdefedOut(block); } + if (cleared || set) { + needUpdate = true; + int delta = TextEditDocumentLayout::braceDepthDelta(block); + if (cleared) + braceDepthDelta += delta; + else if (set) + braceDepthDelta -= delta; + } + + if (braceDepthDelta) + TextEditDocumentLayout::changeBraceDepth(block,braceDepthDelta); + block = block.next(); } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 2466fe7f4a4bf425f6ff16278fa8d889434c50f8..ab2a6ec27634d9a230abe3d724b5e9d45b4ea6dc 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -128,6 +128,7 @@ public: inline void clearParentheses() { m_parentheses.clear(); } inline const Parentheses &parentheses() const { return m_parentheses; } inline bool hasParentheses() const { return !m_parentheses.isEmpty(); } + int braceDepthDelta() const; inline bool setIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = true; return !result; } inline bool clearIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = false; return result;} @@ -215,6 +216,10 @@ public: static bool setIfdefedOut(const QTextBlock &block); static bool clearIfdefedOut(const QTextBlock &block); static bool ifdefedOut(const QTextBlock &block); + static int braceDepthDelta(const QTextBlock &block); + static int braceDepth(const QTextBlock &block); + static void setBraceDepth(QTextBlock &block, int depth); + static void changeBraceDepth(QTextBlock &block, int delta); static TextBlockUserData *testUserData(const QTextBlock &block) { return static_cast<TextBlockUserData*>(block.userData());