diff options
author | Leandro Melo <leandro.melo@nokia.com> | 2010-11-30 14:14:33 +0100 |
---|---|---|
committer | Leandro Melo <leandro.melo@nokia.com> | 2010-12-01 09:07:15 +0100 |
commit | ea8cb4764be669f72472b5f0b056e54f8075e58f (patch) | |
tree | e603b8fe375a06c9eb72c0d22f84c15b9d98a961 | |
parent | e117f04fabde000f4c0aae7cc1a82c58da1ba4c3 (diff) |
Editors: Move auto-completion code out of the editor
This is basically a continuation of the commits which
refactor code out of the base text editor. For instance,
36fa1de4c6a15b2c44736b3491679dd6cfbe27ce and
3a684586fabf103b8e09cef31a18ffae1fd9f0c7.
Also removed the doXXXX() forwarding methods.
21 files changed, 437 insertions, 502 deletions
diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp index 9f1088ada6b..5b3b19db5ad 100644 --- a/src/plugins/cppeditor/cppautocompleter.cpp +++ b/src/plugins/cppeditor/cppautocompleter.cpp @@ -48,8 +48,8 @@ CppAutoCompleter::CppAutoCompleter() CppAutoCompleter::~CppAutoCompleter() {} -bool CppAutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +bool CppAutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) const { QChar ch; @@ -66,7 +66,7 @@ bool CppAutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, return true; } -bool CppAutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool CppAutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -98,7 +98,7 @@ bool CppAutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &curs return true; } -bool CppAutoCompleter::doIsInComment(const QTextCursor &cursor) const +bool CppAutoCompleter::isInComment(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -122,7 +122,7 @@ bool CppAutoCompleter::doIsInComment(const QTextCursor &cursor) const return false; } -QString CppAutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, +QString CppAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text, QChar la, int *skippedChars) const @@ -131,7 +131,7 @@ QString CppAutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, return m.insertMatchingBrace(cursor, text, la, skippedChars); } -QString CppAutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString CppAutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { MatchingText m; return m.insertParagraphSeparator(cursor); diff --git a/src/plugins/cppeditor/cppautocompleter.h b/src/plugins/cppeditor/cppautocompleter.h index 0a80679a9c5..b9ba066e64c 100644 --- a/src/plugins/cppeditor/cppautocompleter.h +++ b/src/plugins/cppeditor/cppautocompleter.h @@ -41,16 +41,15 @@ public: CppAutoCompleter(); virtual ~CppAutoCompleter(); -private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const; - virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; + virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert = QString()) const; + virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; + virtual bool isInComment(const QTextCursor &cursor) const; + virtual QString insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar la, + int *skippedChars) const; + virtual QString insertParagraphSeparator(const QTextCursor &cursor) const; }; } // Internal diff --git a/src/plugins/cppeditor/cppqtstyleindenter.cpp b/src/plugins/cppeditor/cppqtstyleindenter.cpp index 796165c2ae1..778a8c22916 100644 --- a/src/plugins/cppeditor/cppqtstyleindenter.cpp +++ b/src/plugins/cppeditor/cppqtstyleindenter.cpp @@ -47,7 +47,7 @@ CppQtStyleIndenter::CppQtStyleIndenter() CppQtStyleIndenter::~CppQtStyleIndenter() {} -bool CppQtStyleIndenter::doIsElectricalCharacter(const QChar &ch) const +bool CppQtStyleIndenter::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('{') || ch == QLatin1Char('}') || @@ -58,10 +58,10 @@ bool CppQtStyleIndenter::doIsElectricalCharacter(const QChar &ch) const return false; } -void CppQtStyleIndenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void CppQtStyleIndenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { Q_UNUSED(doc) @@ -86,10 +86,10 @@ void CppQtStyleIndenter::doIndentBlock(QTextDocument *doc, ts.indentLine(block, indent + padding, padding); } -void CppQtStyleIndenter::doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void CppQtStyleIndenter::indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); diff --git a/src/plugins/cppeditor/cppqtstyleindenter.h b/src/plugins/cppeditor/cppqtstyleindenter.h index 4c91a1aa374..f1864793124 100644 --- a/src/plugins/cppeditor/cppqtstyleindenter.h +++ b/src/plugins/cppeditor/cppqtstyleindenter.h @@ -41,17 +41,16 @@ public: CppQtStyleIndenter(); virtual ~CppQtStyleIndenter(); -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); - - virtual void doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual bool isElectricCharacter(const QChar &ch) const; + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); + + virtual void indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); }; } // Internal diff --git a/src/plugins/glsleditor/glslautocompleter.cpp b/src/plugins/glsleditor/glslautocompleter.cpp index acb30446413..dc29d26c903 100644 --- a/src/plugins/glsleditor/glslautocompleter.cpp +++ b/src/plugins/glsleditor/glslautocompleter.cpp @@ -47,8 +47,8 @@ GLSLCompleter::GLSLCompleter() GLSLCompleter::~GLSLCompleter() {} -bool GLSLCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +bool GLSLCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) const { QChar ch; @@ -65,7 +65,7 @@ bool GLSLCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, return true; } -bool GLSLCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool GLSLCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -97,7 +97,7 @@ bool GLSLCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) return true; } -bool GLSLCompleter::doIsInComment(const QTextCursor &cursor) const +bool GLSLCompleter::isInComment(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -121,16 +121,16 @@ bool GLSLCompleter::doIsInComment(const QTextCursor &cursor) const return false; } -QString GLSLCompleter::doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const +QString GLSLCompleter::insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar la, + int *skippedChars) const { MatchingText m; return m.insertMatchingBrace(cursor, text, la, skippedChars); } -QString GLSLCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString GLSLCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { MatchingText m; return m.insertParagraphSeparator(cursor); diff --git a/src/plugins/glsleditor/glslautocompleter.h b/src/plugins/glsleditor/glslautocompleter.h index 1fb01991caf..3976883c2e4 100644 --- a/src/plugins/glsleditor/glslautocompleter.h +++ b/src/plugins/glsleditor/glslautocompleter.h @@ -41,16 +41,15 @@ public: GLSLCompleter(); virtual ~GLSLCompleter(); -private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const; - virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; + virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert = QString()) const; + virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; + virtual bool isInComment(const QTextCursor &cursor) const; + virtual QString insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar la, + int *skippedChars) const; + virtual QString insertParagraphSeparator(const QTextCursor &cursor) const; }; } // Internal diff --git a/src/plugins/glsleditor/glslindenter.cpp b/src/plugins/glsleditor/glslindenter.cpp index 8fecc7e2d3b..86a216164ee 100644 --- a/src/plugins/glsleditor/glslindenter.cpp +++ b/src/plugins/glsleditor/glslindenter.cpp @@ -47,7 +47,7 @@ GLSLIndenter::GLSLIndenter() GLSLIndenter::~GLSLIndenter() {} -bool GLSLIndenter::doIsElectricalCharacter(const QChar &ch) const +bool GLSLIndenter::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('{') || ch == QLatin1Char('}') || @@ -58,10 +58,10 @@ bool GLSLIndenter::doIsElectricalCharacter(const QChar &ch) const return false; } -void GLSLIndenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void GLSLIndenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { Q_UNUSED(doc) @@ -86,10 +86,10 @@ void GLSLIndenter::doIndentBlock(QTextDocument *doc, ts.indentLine(block, indent + padding, padding); } -void GLSLIndenter::doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void GLSLIndenter::indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); diff --git a/src/plugins/glsleditor/glslindenter.h b/src/plugins/glsleditor/glslindenter.h index 03af9f378ce..816044ed2b3 100644 --- a/src/plugins/glsleditor/glslindenter.h +++ b/src/plugins/glsleditor/glslindenter.h @@ -41,17 +41,16 @@ public: GLSLIndenter(); virtual ~GLSLIndenter(); -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); - - virtual void doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual bool isElectricCharacter(const QChar &ch) const; + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); + + virtual void indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); }; } // Internal diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp index 836e5e0ef97..845e54e010d 100644 --- a/src/plugins/qmljseditor/qmljsautocompleter.cpp +++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp @@ -143,8 +143,8 @@ AutoCompleter::AutoCompleter() AutoCompleter::~AutoCompleter() {} -bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) const { QChar ch; @@ -200,7 +200,7 @@ bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, return true; } -bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { Token token = tokenUnderCursor(cursor); switch (token.kind) { @@ -212,15 +212,15 @@ bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) } } -bool AutoCompleter::doIsInComment(const QTextCursor &cursor) const +bool AutoCompleter::isInComment(const QTextCursor &cursor) const { return tokenUnderCursor(cursor).is(Token::Comment); } -QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar, - int *skippedChars) const +QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar, + int *skippedChars) const { if (text.length() != 1) return QString(); @@ -268,7 +268,7 @@ QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, return QString(); } -QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { if (shouldInsertNewline(cursor)) { QTextCursor cursor = cursor; diff --git a/src/plugins/qmljseditor/qmljsautocompleter.h b/src/plugins/qmljseditor/qmljsautocompleter.h index 7e6b2bab03f..003a01994b3 100644 --- a/src/plugins/qmljseditor/qmljsautocompleter.h +++ b/src/plugins/qmljseditor/qmljsautocompleter.h @@ -41,16 +41,15 @@ public: AutoCompleter(); virtual ~AutoCompleter(); -private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &tc, + virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert = QString()) const; + virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; + virtual bool isInComment(const QTextCursor &cursor) const; + virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar la, int *skippedChars) const; - virtual QString doInsertParagraphSeparator(const QTextCursor &tc) const; + virtual QString insertParagraphSeparator(const QTextCursor &tc) const; }; } // Internal diff --git a/src/plugins/qmljseditor/qmljsindenter.cpp b/src/plugins/qmljseditor/qmljsindenter.cpp index 81374504ea4..ac288f236de 100644 --- a/src/plugins/qmljseditor/qmljsindenter.cpp +++ b/src/plugins/qmljseditor/qmljsindenter.cpp @@ -47,7 +47,7 @@ Indenter::Indenter() Indenter::~Indenter() {} -bool Indenter::doIsElectricalCharacter(const QChar &ch) const +bool Indenter::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('}') || ch == QLatin1Char(']') @@ -56,10 +56,10 @@ bool Indenter::doIsElectricalCharacter(const QChar &ch) const return false; } -void Indenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void Indenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { Q_UNUSED(doc) Q_UNUSED(typedChar) diff --git a/src/plugins/qmljseditor/qmljsindenter.h b/src/plugins/qmljseditor/qmljsindenter.h index 82ad7114421..cf23112b733 100644 --- a/src/plugins/qmljseditor/qmljsindenter.h +++ b/src/plugins/qmljseditor/qmljsindenter.h @@ -41,12 +41,11 @@ public: Indenter(); virtual ~Indenter(); -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual bool isElectricCharacter(const QChar &ch) const; + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); }; } // Internal diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp index 92ce3161a40..5f04201436c 100644 --- a/src/plugins/texteditor/autocompleter.cpp +++ b/src/plugins/texteditor/autocompleter.cpp @@ -28,69 +28,310 @@ **************************************************************************/ #include "autocompleter.h" +#include "basetextdocumentlayout.h" +#include "texteditorsettings.h" +#include "tabsettings.h" #include <QtGui/QTextCursor> using namespace TextEditor; -AutoCompleter::AutoCompleter() +AutoCompleter::AutoCompleter() : + m_allowSkippingOfBlockEnd(false), + m_surroundWithEnabled(true), + m_autoParenthesesEnabled(true) {} AutoCompleter::~AutoCompleter() {} -bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +void AutoCompleter::setAutoParenthesesEnabled(bool b) { - return doContextAllowsAutoParentheses(cursor, textToInsert); + m_autoParenthesesEnabled = b; } -bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const +bool AutoCompleter::isAutoParenthesesEnabled() const { - return doContextAllowsElectricCharacters(cursor); + return m_autoParenthesesEnabled; } -bool AutoCompleter::isInComment(const QTextCursor &cursor) const +void AutoCompleter::setSurroundWithEnabled(bool b) { - return doIsInComment(cursor); + m_surroundWithEnabled = b; } -QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const - QString &text, - QChar la, - int *skippedChars) const +bool AutoCompleter::isSurroundWithEnabled() const { - return doInsertMatchingBrace(cursor, text, la, skippedChars); + return m_surroundWithEnabled; } -QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const +void AutoCompleter::countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen) +{ + if (c == open) + ++*stillopen; + else if (c == close) + --*stillopen; + + if (*stillopen < 0) { + *errors += -1 * (*stillopen); + *stillopen = 0; + } +} + +void AutoCompleter::countBrackets(QTextCursor cursor, + int from, + int end, + QChar open, + QChar close, + int *errors, + int *stillopen) +{ + cursor.setPosition(from); + QTextBlock block = cursor.block(); + while (block.isValid() && block.position() < end) { + TextEditor::Parentheses parenList = TextEditor::BaseTextDocumentLayout::parentheses(block); + if (!parenList.isEmpty() && !TextEditor::BaseTextDocumentLayout::ifdefedOut(block)) { + for (int i = 0; i < parenList.count(); ++i) { + TextEditor::Parenthesis paren = parenList.at(i); + int position = block.position() + paren.pos; + if (position < from || position >= end) + continue; + countBracket(open, close, paren.chr, errors, stillopen); + } + } + block = block.next(); + } +} + +QString AutoCompleter::autoComplete(QTextCursor &cursor, const QString &textToInsert) const +{ + const bool checkBlockEnd = m_allowSkippingOfBlockEnd; + m_allowSkippingOfBlockEnd = false; // consume blockEnd. + + if (m_surroundWithEnabled && cursor.hasSelection()) { + if (textToInsert == QLatin1String("(")) + return cursor.selectedText() + QLatin1String(")"); + if (textToInsert == QLatin1String("{")) { + //If the text span multiple lines, insert on different lines + QString str = cursor.selectedText(); + if (str.contains(QChar::ParagraphSeparator)) { + //Also, try to simulate auto-indent + str = (str.startsWith(QChar::ParagraphSeparator) ? QString() : QString(QChar::ParagraphSeparator)) + + str; + if (str.endsWith(QChar::ParagraphSeparator)) + str += QLatin1String("}") + QString(QChar::ParagraphSeparator); + else + str += QString(QChar::ParagraphSeparator) + QLatin1String("}"); + } + else { + str += QLatin1String("}"); + } + return str; + } + if (textToInsert == QLatin1String("[")) + return cursor.selectedText() + QLatin1String("]"); + if (textToInsert == QLatin1String("\"")) + return cursor.selectedText() + QLatin1String("\""); + if (textToInsert == QLatin1String("'")) + return cursor.selectedText() + QLatin1String("'"); + } + + if (!m_autoParenthesesEnabled) + return QString(); + + if (!contextAllowsAutoParentheses(cursor, textToInsert)) + return QString(); + + QTextDocument *doc = cursor.document(); + const QString text = textToInsert; + const QChar lookAhead = doc->characterAt(cursor.selectionEnd()); + + const QChar character = textToInsert.at(0); + const QString parentheses = QLatin1String("()"); + const QString brackets = QLatin1String("[]"); + if (parentheses.contains(character) || brackets.contains(character)) { + QTextCursor tmp= cursor; + bool foundBlockStart = TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); + int blockStart = foundBlockStart ? tmp.position() : 0; + tmp = cursor; + bool foundBlockEnd = TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); + int blockEnd = foundBlockEnd ? tmp.position() : (cursor.document()->characterCount() - 1); + const QChar openChar = parentheses.contains(character) ? QLatin1Char('(') : QLatin1Char('['); + const QChar closeChar = parentheses.contains(character) ? QLatin1Char(')') : QLatin1Char(']'); + + int errors = 0; + int stillopen = 0; + countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsBeforeInsertion = errors + stillopen; + errors = 0; + stillopen = 0; + countBrackets(cursor, blockStart, cursor.position(), openChar, closeChar, &errors, &stillopen); + countBracket(openChar, closeChar, character, &errors, &stillopen); + countBrackets(cursor, cursor.position(), blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsAfterInsertion = errors + stillopen; + if (errorsAfterInsertion < errorsBeforeInsertion) + return QString(); // insertion fixes parentheses or bracket errors, do not auto complete + } + + int skippedChars = 0; + const QString autoText = insertMatchingBrace(cursor, text, lookAhead, &skippedChars); + + if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) { + if (textToInsert.length() > 1) + qWarning() << "*** handle event compression"; + + int startPos = cursor.selectionEnd(), pos = startPos; + while (doc->characterAt(pos).isSpace()) + ++pos; + + if (doc->characterAt(pos) == QLatin1Char('}')) + skippedChars += (pos - startPos) + 1; + } + + if (skippedChars) { + const int pos = cursor.position(); + cursor.setPosition(pos + skippedChars); + cursor.setPosition(pos, QTextCursor::KeepAnchor); + } + + return autoText; +} + +bool AutoCompleter::autoBackspace(QTextCursor &cursor) { - return doInsertParagraphSeparator(cursor); + m_allowSkippingOfBlockEnd = false; + + if (!m_autoParenthesesEnabled) + return false; + + int pos = cursor.position(); + if (pos == 0) + return false; + QTextCursor c = cursor; + c.setPosition(pos - 1); + + QTextDocument *doc = cursor.document(); + const QChar lookAhead = doc->characterAt(pos); + const QChar lookBehind = doc->characterAt(pos - 1); + const QChar lookFurtherBehind = doc->characterAt(pos - 2); + + const QChar character = lookBehind; + if (character == QLatin1Char('(') || character == QLatin1Char('[')) { + QTextCursor tmp = cursor; + TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); + int blockStart = tmp.isNull() ? 0 : tmp.position(); + tmp = cursor; + TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); + int blockEnd = tmp.isNull() ? (cursor.document()->characterCount()-1) : tmp.position(); + QChar openChar = character; + QChar closeChar = (character == QLatin1Char('(')) ? QLatin1Char(')') : QLatin1Char(']'); + + int errors = 0; + int stillopen = 0; + countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsBeforeDeletion = errors + stillopen; + errors = 0; + stillopen = 0; + countBrackets(cursor, blockStart, pos - 1, openChar, closeChar, &errors, &stillopen); + countBrackets(cursor, pos, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsAfterDeletion = errors + stillopen; + + if (errorsAfterDeletion < errorsBeforeDeletion) + return false; // insertion fixes parentheses or bracket errors, do not auto complete + } + + // ### this code needs to be generalized + if ((lookBehind == QLatin1Char('(') && lookAhead == QLatin1Char(')')) + || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']')) + || (lookBehind == QLatin1Char('"') && lookAhead == QLatin1Char('"') + && lookFurtherBehind != QLatin1Char('\\')) + || (lookBehind == QLatin1Char('\'') && lookAhead == QLatin1Char('\'') + && lookFurtherBehind != QLatin1Char('\\'))) { + if (! isInComment(c)) { + cursor.beginEditBlock(); + cursor.deleteChar(); + cursor.deletePreviousChar(); + cursor.endEditBlock(); + return true; + } + } + return false; } -bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +int AutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor) +{ + if (!m_autoParenthesesEnabled) + return 0; + + QTextDocument *doc = cursor.document(); + if (doc->characterAt(cursor.position() - 1) != QLatin1Char('{')) + return 0; + + if (!contextAllowsAutoParentheses(cursor)) + return 0; + + // verify that we indeed do have an extra opening brace in the document + int braceDepth = BaseTextDocumentLayout::braceDepth(doc->lastBlock()); + + if (braceDepth <= 0) + return 0; // braces are all balanced or worse, no need to do anything + + // we have an extra brace , let's see if we should close it + + /* verify that the next block is not further intended compared to the current block. + This covers the following case: + + if (condition) {| + statement; + */ + const TabSettings &ts = TextEditorSettings::instance()->tabSettings(); + QTextBlock block = cursor.block(); + int indentation = ts.indentationColumn(block.text()); + + if (block.next().isValid()) { // not the last block + block = block.next(); + //skip all empty blocks + while (block.isValid() && ts.onlySpace(block.text())) + block = block.next(); + if (block.isValid() + && ts.indentationColumn(block.text()) > indentation) + return 0; + } + + const QString &textToInsert = insertParagraphSeparator(cursor); + int pos = cursor.position(); + cursor.insertBlock(); + cursor.insertText(textToInsert); + cursor.setPosition(pos); + + m_allowSkippingOfBlockEnd = true; + + return 1; +} + +bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) const { Q_UNUSED(cursor); Q_UNUSED(textToInsert); return false; } -bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { - return doContextAllowsAutoParentheses(cursor); + return contextAllowsAutoParentheses(cursor); } -bool AutoCompleter::doIsInComment(const QTextCursor &cursor) const +bool AutoCompleter::isInComment(const QTextCursor &cursor) const { Q_UNUSED(cursor); return false; } -QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const +QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar la, + int *skippedChars) const { Q_UNUSED(cursor); Q_UNUSED(text); @@ -99,7 +340,7 @@ QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, return QString(); } -QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { Q_UNUSED(cursor); return QString(); diff --git a/src/plugins/texteditor/autocompleter.h b/src/plugins/texteditor/autocompleter.h index 3b49d499a4e..f8ecc1ce49a 100644 --- a/src/plugins/texteditor/autocompleter.h +++ b/src/plugins/texteditor/autocompleter.h @@ -47,30 +47,45 @@ public: AutoCompleter(); virtual ~AutoCompleter(); - bool contextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; + void setAutoParenthesesEnabled(bool b); + bool isAutoParenthesesEnabled() const; + + void setSurroundWithEnabled(bool b); + bool isSurroundWithEnabled() const; + + // Returns the text to complete at the cursor position, or an empty string + virtual QString autoComplete(QTextCursor &cursor, const QString &text) const; + + // Handles backspace. When returning true, backspace processing is stopped + virtual bool autoBackspace(QTextCursor &cursor); + + // Hook to insert special characters on enter. Returns the number of extra blocks inserted. + virtual int paragraphSeparatorAboutToBeInserted(QTextCursor &cursor); + + virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert = QString()) const; + virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; // Returns true if the cursor is inside a comment. - bool isInComment(const QTextCursor &cursor) const; + virtual bool isInComment(const QTextCursor &cursor) const; + + virtual QString insertMatchingBrace(const QTextCursor &cursor, const + QString &text, + QChar la, + int *skippedChars) const; - QString insertMatchingBrace(const QTextCursor &cursor, const - QString &text, - QChar la, - int *skippedChars) const; // Returns the text that needs to be inserted - QString insertParagraphSeparator(const QTextCursor &cursor) const; + virtual QString insertParagraphSeparator(const QTextCursor &cursor) const; + +protected: + static void countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen); + static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close, + int *errors, int *stillopen); private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const; - virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; + mutable bool m_allowSkippingOfBlockEnd; + bool m_surroundWithEnabled; + bool m_autoParenthesesEnabled; }; } // TextEditor diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 1e58cf2265c..7fcea6ccdab 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1552,8 +1552,9 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) const TabSettings &ts = d->m_document->tabSettings(); cursor.beginEditBlock(); - int extraBlocks = paragraphSeparatorAboutToBeInserted(cursor); // virtual + int extraBlocks = d->m_autoCompleter->paragraphSeparatorAboutToBeInserted(cursor); + QString previousIndentationString; if (ts.m_autoIndent) { cursor.insertBlock(); indent(document(), cursor, QChar::Null); @@ -1561,8 +1562,10 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) cursor.insertBlock(); // After inserting the block, to avoid duplicating whitespace on the same line - const QString previousBlockText = cursor.block().previous().text(); - cursor.insertText(ts.indentationString(previousBlockText)); + const QString &previousBlockText = cursor.block().previous().text(); + previousIndentationString = ts.indentationString(previousBlockText); + if (!previousIndentationString.isEmpty()) + cursor.insertText(previousIndentationString); } cursor.endEditBlock(); e->accept(); @@ -1572,6 +1575,10 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) while (extraBlocks > 0) { --extraBlocks; ensureVisible.movePosition(QTextCursor::NextBlock); + if (ts.m_autoIndent) + indent(document(), ensureVisible, QChar::Null); + else if (!previousIndentationString.isEmpty()) + ensureVisible.insertText(previousIndentationString); } setTextCursor(ensureVisible); } @@ -1763,7 +1770,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) } else if ((e->modifiers() & (Qt::ControlModifier|Qt::AltModifier)) != Qt::ControlModifier){ QTextCursor cursor = textCursor(); QString text = e->text(); - QString autoText = autoComplete(cursor, text); + const QString &autoText = d->m_autoCompleter->autoComplete(cursor, text); QChar electricChar; if (d->m_document->tabSettings().m_autoIndent) { @@ -2178,26 +2185,6 @@ bool BaseTextEditor::isParenthesesMatchingEnabled() const return d->m_parenthesesMatchingEnabled; } -void BaseTextEditor::setAutoParenthesesEnabled(bool b) -{ - d->m_autoParenthesesEnabled = b; -} - -bool BaseTextEditor::isAutoParenthesesEnabled() const -{ - return d->m_autoParenthesesEnabled; -} - -void BaseTextEditor::setSurroundWithEnabled(bool b) -{ - d->m_surroundWithEnabled= b; -} - -bool BaseTextEditor::isSurroundWithEnabled() const -{ - return d->m_surroundWithEnabled; -} - void BaseTextEditor::setHighlightCurrentLine(bool b) { d->m_highlightCurrentLine = b; @@ -2359,11 +2346,8 @@ BaseTextEditorPrivate::BaseTextEditorPrivate() q(0), m_contentsChanged(false), m_lastCursorChangeWasInteresting(false), - m_allowSkippingOfBlockEnd(false), m_document(new BaseTextDocument), m_parenthesesMatchingEnabled(false), - m_autoParenthesesEnabled(true), - m_surroundWithEnabled(true), m_updateTimer(0), m_formatRange(false), m_parenthesesMatchingTimer(0), @@ -4413,7 +4397,7 @@ void BaseTextEditor::handleBackspaceKey() const TextEditor::TabSettings &tabSettings = d->m_document->tabSettings(); - if (tabSettings.m_autoIndent && autoBackspace(cursor)) + if (tabSettings.m_autoIndent && d->m_autoCompleter->autoBackspace(cursor)) return; if (!tabSettings.m_smartBackspace) { @@ -4487,250 +4471,6 @@ void BaseTextEditor::indentInsertedText(const QTextCursor &tc) indent(tc.document(), tc, QChar::Null); } -void BaseTextEditor::countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen) -{ - if (c == open) - ++*stillopen; - else if (c == close) - --*stillopen; - - if (*stillopen < 0) { - *errors += -1 * (*stillopen); - *stillopen = 0; - } -} - -void BaseTextEditor::countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close, int *errors, int *stillopen) -{ - cursor.setPosition(from); - QTextBlock block = cursor.block(); - while (block.isValid() && block.position() < end) { - TextEditor::Parentheses parenList = TextEditor::BaseTextDocumentLayout::parentheses(block); - if (!parenList.isEmpty() && !TextEditor::BaseTextDocumentLayout::ifdefedOut(block)) { - for (int i = 0; i < parenList.count(); ++i) { - TextEditor::Parenthesis paren = parenList.at(i); - int position = block.position() + paren.pos; - if (position < from || position >= end) - continue; - countBracket(open, close, paren.chr, errors, stillopen); - } - } - block = block.next(); - } -} - -QString BaseTextEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert) const -{ - const bool checkBlockEnd = d->m_allowSkippingOfBlockEnd; - d->m_allowSkippingOfBlockEnd = false; // consume blockEnd. - - if (d->m_surroundWithEnabled && cursor.hasSelection()) { - if (textToInsert == QLatin1String("(")) - return cursor.selectedText() + QLatin1String(")"); - if (textToInsert == QLatin1String("{")) { - //If the text span multiple lines, insert on different lines - QString str = cursor.selectedText(); - if (str.contains(QChar::ParagraphSeparator)) { - //Also, try to simulate auto-indent - str = (str.startsWith(QChar::ParagraphSeparator) ? QString() : QString(QChar::ParagraphSeparator)) + - str; - if (str.endsWith(QChar::ParagraphSeparator)) - str += QLatin1String("}") + QString(QChar::ParagraphSeparator); - else - str += QString(QChar::ParagraphSeparator) + QLatin1String("}"); - } - else { - str += QLatin1String("}"); - } - return str; - } - if (textToInsert == QLatin1String("[")) - return cursor.selectedText() + QLatin1String("]"); - if (textToInsert == QLatin1String("\"")) - return cursor.selectedText() + QLatin1String("\""); - if (textToInsert == QLatin1String("'")) - return cursor.selectedText() + QLatin1String("'"); - } - - if (!d->m_autoParenthesesEnabled) - return QString(); - - if (!d->m_autoCompleter->contextAllowsAutoParentheses(cursor, textToInsert)) - return QString(); - - const QString text = textToInsert; - const QChar lookAhead = characterAt(cursor.selectionEnd()); - - const QChar character = textToInsert.at(0); - const QString parentheses = QLatin1String("()"); - const QString brackets = QLatin1String("[]"); - if (parentheses.contains(character) || brackets.contains(character)) { - QTextCursor tmp= cursor; - bool foundBlockStart = TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); - int blockStart = foundBlockStart ? tmp.position() : 0; - tmp = cursor; - bool foundBlockEnd = TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); - int blockEnd = foundBlockEnd ? tmp.position() : (cursor.document()->characterCount() - 1); - const QChar openChar = parentheses.contains(character) ? QLatin1Char('(') : QLatin1Char('['); - const QChar closeChar = parentheses.contains(character) ? QLatin1Char(')') : QLatin1Char(']'); - - int errors = 0; - int stillopen = 0; - countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsBeforeInsertion = errors + stillopen; - errors = 0; - stillopen = 0; - countBrackets(cursor, blockStart, cursor.position(), openChar, closeChar, &errors, &stillopen); - countBracket(openChar, closeChar, character, &errors, &stillopen); - countBrackets(cursor, cursor.position(), blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsAfterInsertion = errors + stillopen; - if (errorsAfterInsertion < errorsBeforeInsertion) - return QString(); // insertion fixes parentheses or bracket errors, do not auto complete - } - - int skippedChars = 0; - const QString autoText = d->m_autoCompleter->insertMatchingBrace(cursor, text, lookAhead, &skippedChars); - - if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) { - if (textToInsert.length() > 1) - qWarning() << "*** handle event compression"; - - int startPos = cursor.selectionEnd(), pos = startPos; - while (characterAt(pos).isSpace()) - ++pos; - - if (characterAt(pos) == QLatin1Char('}')) - skippedChars += (pos - startPos) + 1; - } - - if (skippedChars) { - const int pos = cursor.position(); - cursor.setPosition(pos + skippedChars); - cursor.setPosition(pos, QTextCursor::KeepAnchor); - } - - return autoText; -} - -bool BaseTextEditor::autoBackspace(QTextCursor &cursor) -{ - d->m_allowSkippingOfBlockEnd = false; - - if (!d->m_autoParenthesesEnabled) - return false; - - int pos = cursor.position(); - if (pos == 0) - return false; - QTextCursor c = cursor; - c.setPosition(pos - 1); - - const QChar lookAhead = characterAt(pos); - const QChar lookBehind = characterAt(pos - 1); - const QChar lookFurtherBehind = characterAt(pos - 2); - - const QChar character = lookBehind; - if (character == QLatin1Char('(') || character == QLatin1Char('[')) { - QTextCursor tmp = cursor; - TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); - int blockStart = tmp.isNull() ? 0 : tmp.position(); - tmp = cursor; - TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); - int blockEnd = tmp.isNull() ? (cursor.document()->characterCount()-1) : tmp.position(); - QChar openChar = character; - QChar closeChar = (character == QLatin1Char('(')) ? QLatin1Char(')') : QLatin1Char(']'); - - int errors = 0; - int stillopen = 0; - countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsBeforeDeletion = errors + stillopen; - errors = 0; - stillopen = 0; - countBrackets(cursor, blockStart, pos - 1, openChar, closeChar, &errors, &stillopen); - countBrackets(cursor, pos, blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsAfterDeletion = errors + stillopen; - - if (errorsAfterDeletion < errorsBeforeDeletion) - return false; // insertion fixes parentheses or bracket errors, do not auto complete - } - - // ### this code needs to be generalized - if ((lookBehind == QLatin1Char('(') && lookAhead == QLatin1Char(')')) - || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']')) - || (lookBehind == QLatin1Char('"') && lookAhead == QLatin1Char('"') - && lookFurtherBehind != QLatin1Char('\\')) - || (lookBehind == QLatin1Char('\'') && lookAhead == QLatin1Char('\'') - && lookFurtherBehind != QLatin1Char('\\'))) { - if (! d->m_autoCompleter->isInComment(c)) { - cursor.beginEditBlock(); - cursor.deleteChar(); - cursor.deletePreviousChar(); - cursor.endEditBlock(); - return true; - } - } - return false; -} - -int BaseTextEditor::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor) -{ - if (!d->m_autoParenthesesEnabled) - return 0; - - if (characterAt(cursor.position() - 1) != QLatin1Char('{')) - return 0; - - if (!d->m_autoCompleter->contextAllowsAutoParentheses(cursor)) - return 0; - - // verify that we indeed do have an extra opening brace in the document - int braceDepth = BaseTextDocumentLayout::braceDepth(document()->lastBlock()); - - if (braceDepth <= 0) - return 0; // braces are all balanced or worse, no need to do anything - - // we have an extra brace , let's see if we should close it - - - /* verify that the next block is not further intended compared to the current block. - This covers the following case: - - if (condition) {| - statement; - */ - const TabSettings &ts = tabSettings(); - QTextBlock block = cursor.block(); - int indentation = ts.indentationColumn(block.text()); - - if (block.next().isValid()) { // not the last block - block = block.next(); - //skip all empty blocks - while (block.isValid() && ts.onlySpace(block.text())) - block = block.next(); - if (block.isValid() - && ts.indentationColumn(block.text()) > indentation) - return 0; - } - - int pos = cursor.position(); - - const QString textToInsert = d->m_autoCompleter->insertParagraphSeparator(cursor); - - cursor.insertText(textToInsert); - cursor.setPosition(pos); - if (ts.m_autoIndent) { - cursor.insertBlock(); - indent(document(), cursor, QChar::Null); - } else { - QString previousBlockText = cursor.block().text(); - cursor.insertBlock(); - cursor.insertText(ts.indentationString(previousBlockText)); - } - cursor.setPosition(pos); - d->m_allowSkippingOfBlockEnd = true; - return 1; -} - void BaseTextEditor::indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar) { maybeClearSomeExtraSelections(cursor); @@ -5624,7 +5364,8 @@ void BaseTextEditor::setStorageSettings(const StorageSettings &storageSettings) void BaseTextEditor::setCompletionSettings(const TextEditor::CompletionSettings &completionSettings) { - setAutoParenthesesEnabled(completionSettings.m_autoInsertBrackets); + d->m_autoCompleter->setAutoParenthesesEnabled(completionSettings.m_autoInsertBrackets); + d->m_autoCompleter->setSurroundWithEnabled(completionSettings.m_autoInsertBrackets); } void BaseTextEditor::fold() diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index c6e3fe6ef79..dcb590e6318 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -168,12 +168,6 @@ public: void setParenthesesMatchingEnabled(bool b); bool isParenthesesMatchingEnabled() const; - void setAutoParenthesesEnabled(bool b); - bool isAutoParenthesesEnabled() const; - - void setSurroundWithEnabled(bool b); - bool isSurroundWithEnabled() const; - void setHighlightCurrentLine(bool b); bool highlightCurrentLine() const; @@ -424,24 +418,10 @@ protected: void dragEnterEvent(QDragEnterEvent *e); public: - // Returns the text to complete at the cursor position, or an empty string - virtual QString autoComplete(QTextCursor &cursor, const QString &text) const; - // Handles backspace. When returning true, backspace processing is stopped - virtual bool autoBackspace(QTextCursor &cursor); - // Hook to insert special characters on enter. Returns the number of extra blocks inserted. - virtual int paragraphSeparatorAboutToBeInserted(QTextCursor &cursor); - void indentInsertedText(const QTextCursor &tc); void indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar); void reindent(QTextDocument *doc, const QTextCursor &cursor); -protected: - static void countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen); - - static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close, - int *errors, int *stillopen); - -public: struct Link { Link(const QString &fileName = QString(), diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 3fd10bc054b..d658899cd1a 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -180,7 +180,6 @@ public: BaseTextEditor *q; bool m_contentsChanged; bool m_lastCursorChangeWasInteresting; - bool m_allowSkippingOfBlockEnd; QList<QTextEdit::ExtraSelection> m_syntaxHighlighterSelections; QTextEdit::ExtraSelection m_lineSelection; @@ -191,8 +190,6 @@ public: QString m_displayName; bool m_parenthesesMatchingEnabled; - bool m_autoParenthesesEnabled; - bool m_surroundWithEnabled; QTimer *m_updateTimer; Utils::ChangeSet m_changeSet; diff --git a/src/plugins/texteditor/indenter.cpp b/src/plugins/texteditor/indenter.cpp index 97ae9ebf17c..3a833cd0976 100644 --- a/src/plugins/texteditor/indenter.cpp +++ b/src/plugins/texteditor/indenter.cpp @@ -39,38 +39,12 @@ Indenter::Indenter() Indenter::~Indenter() {} -bool Indenter::isElectricCharacter(const QChar &ch) const -{ - return doIsElectricalCharacter(ch); -} - -void Indenter::indentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor) -{ - doIndentBlock(doc, block, typedChar, editor); -} - -void Indenter::indent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - BaseTextEditor *editor) -{ - doIndent(doc, cursor, typedChar, editor); -} - -void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor) -{ - doReindent(doc, cursor, editor); -} - -bool Indenter::doIsElectricalCharacter(const QChar &) const +bool Indenter::isElectricCharacter(const QChar &) const { return false; } -void Indenter::doIndentBlock(QTextDocument *doc, +void Indenter::indentBlock(QTextDocument *doc, const QTextBlock &block, const QChar &typedChar, BaseTextEditor *editor) @@ -81,7 +55,10 @@ void Indenter::doIndentBlock(QTextDocument *doc, Q_UNUSED(editor); } -void Indenter::doIndent(QTextDocument *doc, const QTextCursor &cursor, const QChar &typedChar, BaseTextEditor *editor) +void Indenter::indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); @@ -95,7 +72,7 @@ void Indenter::doIndent(QTextDocument *doc, const QTextCursor &cursor, const QCh } } -void Indenter::doReindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor) +void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); diff --git a/src/plugins/texteditor/indenter.h b/src/plugins/texteditor/indenter.h index 22a95b888ed..49e8546e7ff 100644 --- a/src/plugins/texteditor/indenter.h +++ b/src/plugins/texteditor/indenter.h @@ -51,32 +51,23 @@ public: virtual ~Indenter(); // Returns true if key triggers an indent. - bool isElectricCharacter(const QChar &ch) const; + virtual bool isElectricCharacter(const QChar &ch) const; + // Indent a text block based on previous line. Default does nothing - void indentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor); + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + BaseTextEditor *editor); + // Indent at cursor. Calls indentBlock for selection or current line. - void indent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - BaseTextEditor *editor); + virtual void indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + BaseTextEditor *editor); + // Reindent at cursor. Selection will be adjusted according to the indentation // change of the first block. - void reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor); - -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor); - virtual void doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - BaseTextEditor *editor); - virtual void doReindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor); + virtual void reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor); }; } // namespace TextEditor diff --git a/src/plugins/texteditor/normalindenter.cpp b/src/plugins/texteditor/normalindenter.cpp index d0c84b210f7..7acb9f78278 100644 --- a/src/plugins/texteditor/normalindenter.cpp +++ b/src/plugins/texteditor/normalindenter.cpp @@ -60,10 +60,10 @@ NormalIndenter::~NormalIndenter() // for additional block being inserted. It might be possible // to do in 2 steps (indenting/wrapping)} // -void NormalIndenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor) +void NormalIndenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + BaseTextEditor *editor) { Q_UNUSED(typedChar) diff --git a/src/plugins/texteditor/normalindenter.h b/src/plugins/texteditor/normalindenter.h index f66bbaef0a0..98be4ed1321 100644 --- a/src/plugins/texteditor/normalindenter.h +++ b/src/plugins/texteditor/normalindenter.h @@ -40,11 +40,10 @@ public: NormalIndenter(); virtual ~NormalIndenter(); -private: - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor); + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + BaseTextEditor *editor); }; } // namespace TextEditor |