diff options
-rw-r--r-- | share/qtcreator/styles/dark.xml | 1 | ||||
-rw-r--r-- | share/qtcreator/styles/grayscale.xml | 1 | ||||
-rw-r--r-- | share/qtcreator/styles/inkpot.xml | 1 | ||||
-rw-r--r-- | share/qtcreator/styles/intellij.xml | 1 | ||||
-rw-r--r-- | src/plugins/texteditor/completionsettings.cpp | 5 | ||||
-rw-r--r-- | src/plugins/texteditor/completionsettings.h | 1 | ||||
-rw-r--r-- | src/plugins/texteditor/completionsettingspage.cpp | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/completionsettingspage.ui | 16 | ||||
-rw-r--r-- | src/plugins/texteditor/fontsettingspage.cpp | 4 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.cpp | 81 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditorconstants.cpp | 1 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditorconstants.h | 1 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditorsettings.cpp | 3 |
13 files changed, 101 insertions, 17 deletions
diff --git a/share/qtcreator/styles/dark.xml b/share/qtcreator/styles/dark.xml index 4a605d3f028..7ce41824c2c 100644 --- a/share/qtcreator/styles/dark.xml +++ b/share/qtcreator/styles/dark.xml @@ -28,6 +28,7 @@ <style name="Operator" foreground="#aaaaaa"/> <style name="Parentheses" foreground="#ff5555" background="#333333"/> <style name="ParenthesesMismatch" background="#800080"/> + <style name="AutoComplete" foreground="#a0a0ff" background="#333333"/> <style name="Preprocessor" foreground="#5555ff"/> <style name="SearchResult" background="#555500"/> <style name="SearchScope" background="#222200"/> diff --git a/share/qtcreator/styles/grayscale.xml b/share/qtcreator/styles/grayscale.xml index d9e7779b462..0ebf9322ff8 100644 --- a/share/qtcreator/styles/grayscale.xml +++ b/share/qtcreator/styles/grayscale.xml @@ -25,6 +25,7 @@ <style name="Operator"/> <style name="Parentheses" background="#e3e3e3" bold="true"/> <style name="ParenthesesMismatch" background="#808080"/> + <style name="AutoComplete" foreground="#303030" background="#d0d0d0"/> <style name="Preprocessor" foreground="#5b5b5b" bold="true"/> <style name="RemovedLine" foreground="#a0a0a4"/> <style name="Static" italic="true"/> diff --git a/share/qtcreator/styles/inkpot.xml b/share/qtcreator/styles/inkpot.xml index 65336e86bf9..2cf8bdcf358 100644 --- a/share/qtcreator/styles/inkpot.xml +++ b/share/qtcreator/styles/inkpot.xml @@ -34,6 +34,7 @@ <style name="Operator" foreground="#cfbfad"/> <style name="Parentheses" foreground="#ffff00" background="#4e4e8f"/> <style name="ParenthesesMismatch" background="#404040"/> + <style name="AutoComplete" foreground="#ffff00" background="#4e4e8f"/> <style name="Preprocessor" foreground="#409090"/> <style name="RemovedLine" foreground="#ff0000"/> <style name="SearchResult" foreground="#000000" background="#ffef0b"/> diff --git a/share/qtcreator/styles/intellij.xml b/share/qtcreator/styles/intellij.xml index 1a34c83bc18..b41d7fc90be 100644 --- a/share/qtcreator/styles/intellij.xml +++ b/share/qtcreator/styles/intellij.xml @@ -17,6 +17,7 @@ <style name="Operator" foreground="#000000"/> <style name="Parentheses" foreground="#ff0000" background="#c3e1ff"/> <style name="ParenthesesMismatch" background="#ff00ff"/> + <style name="AutoComplete" foreground="#ff0000" background="#c3e1ff"/> <style name="Preprocessor" foreground="#000080" bold="true"/> <style name="RemovedLine" foreground="#ff0000"/> <style name="String" foreground="#008000" bold="true"/> diff --git a/src/plugins/texteditor/completionsettings.cpp b/src/plugins/texteditor/completionsettings.cpp index 49e29ba8485..325b7580282 100644 --- a/src/plugins/texteditor/completionsettings.cpp +++ b/src/plugins/texteditor/completionsettings.cpp @@ -38,6 +38,7 @@ static const char surroundingAutoQuotesKey[] = "SurroundingAutoQuotes"; static const char partiallyCompleteKey[] = "PartiallyComplete"; static const char spaceAfterFunctionNameKey[] = "SpaceAfterFunctionName"; static const char autoSplitStringsKey[] = "AutoSplitStrings"; +static const char animateAutoCompleteKey[] = "AnimateAutoComplete"; using namespace TextEditor; @@ -54,6 +55,7 @@ void CompletionSettings::toSettings(QSettings *s) const s->setValue(partiallyCompleteKey, m_partiallyComplete); s->setValue(spaceAfterFunctionNameKey, m_spaceAfterFunctionName); s->setValue(autoSplitStringsKey, m_autoSplitStrings); + s->setValue(animateAutoCompleteKey, m_animateAutoComplete); s->endGroup(); } @@ -82,6 +84,8 @@ void CompletionSettings::fromSettings(QSettings *s) s->value(spaceAfterFunctionNameKey, m_spaceAfterFunctionName).toBool(); m_autoSplitStrings = s->value(autoSplitStringsKey, m_autoSplitStrings).toBool(); + m_animateAutoComplete = + s->value(animateAutoCompleteKey, m_animateAutoComplete).toBool(); s->endGroup(); } @@ -97,5 +101,6 @@ bool CompletionSettings::equals(const CompletionSettings &cs) const && m_partiallyComplete == cs.m_partiallyComplete && m_spaceAfterFunctionName == cs.m_spaceAfterFunctionName && m_autoSplitStrings == cs.m_autoSplitStrings + && m_animateAutoComplete == cs.m_animateAutoComplete ; } diff --git a/src/plugins/texteditor/completionsettings.h b/src/plugins/texteditor/completionsettings.h index 10740b214ec..5dfb172eb27 100644 --- a/src/plugins/texteditor/completionsettings.h +++ b/src/plugins/texteditor/completionsettings.h @@ -66,6 +66,7 @@ public: bool m_partiallyComplete = true; bool m_spaceAfterFunctionName = false; bool m_autoSplitStrings = true; + bool m_animateAutoComplete = true; }; inline bool operator==(const CompletionSettings &t1, const CompletionSettings &t2) { return t1.equals(t2); } diff --git a/src/plugins/texteditor/completionsettingspage.cpp b/src/plugins/texteditor/completionsettingspage.cpp index 8ffd0a345d2..b505eb65661 100644 --- a/src/plugins/texteditor/completionsettingspage.cpp +++ b/src/plugins/texteditor/completionsettingspage.cpp @@ -102,6 +102,7 @@ QWidget *CompletionSettingsPage::widget() m_page->partiallyComplete->setChecked(m_completionSettings.m_partiallyComplete); m_page->spaceAfterFunctionName->setChecked(m_completionSettings.m_spaceAfterFunctionName); m_page->autoSplitStrings->setChecked(m_completionSettings.m_autoSplitStrings); + m_page->animateAutoComplete->setChecked(m_completionSettings.m_animateAutoComplete); m_page->enableDoxygenCheckBox->setChecked(m_commentsSettings.m_enableDoxygen); m_page->generateBriefCheckBox->setChecked(m_commentsSettings.m_generateBrief); @@ -175,6 +176,7 @@ void CompletionSettingsPage::settingsFromUi(CompletionSettings &completion, Comm completion.m_partiallyComplete = m_page->partiallyComplete->isChecked(); completion.m_spaceAfterFunctionName = m_page->spaceAfterFunctionName->isChecked(); completion.m_autoSplitStrings = m_page->autoSplitStrings->isChecked(); + completion.m_animateAutoComplete = m_page->animateAutoComplete->isChecked(); comment.m_enableDoxygen = m_page->enableDoxygenCheckBox->isChecked(); comment.m_generateBrief = m_page->generateBriefCheckBox->isChecked(); diff --git a/src/plugins/texteditor/completionsettingspage.ui b/src/plugins/texteditor/completionsettingspage.ui index 9782e9c0399..d91caeda947 100644 --- a/src/plugins/texteditor/completionsettingspage.ui +++ b/src/plugins/texteditor/completionsettingspage.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>TextEditor::Internal::CompletionSettingsPage</class> - <widget class="QWidget" name="CppTools::Internal::CompletionSettingsPage"> + <widget class="QWidget" name="TextEditor::Internal::CompletionSettingsPage"> <property name="geometry"> <rect> <x>0</x> @@ -214,6 +214,19 @@ In addition, Shift+Enter inserts an escape character at the cursor position and </property> </widget> </item> + <item row="2" column="1"> + <widget class="QCheckBox" name="animateAutoComplete"> + <property name="toolTip"> + <string>Show a visual hint when for example a brace or a quote is automatically inserted by the editor.</string> + </property> + <property name="text"> + <string>Animate automatically inserted text</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> </layout> </widget> </item> @@ -302,6 +315,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and <tabstop>surroundBrackets</tabstop> <tabstop>surroundQuotes</tabstop> <tabstop>spaceAfterFunctionName</tabstop> + <tabstop>animateAutoComplete</tabstop> <tabstop>enableDoxygenCheckBox</tabstop> <tabstop>generateBriefCheckBox</tabstop> <tabstop>leadingAsterisksCheckBox</tabstop> diff --git a/src/plugins/texteditor/fontsettingspage.cpp b/src/plugins/texteditor/fontsettingspage.cpp index d458f1e5a18..0fb6dcbb54e 100644 --- a/src/plugins/texteditor/fontsettingspage.cpp +++ b/src/plugins/texteditor/fontsettingspage.cpp @@ -263,6 +263,8 @@ QColor FormatDescription::foreground() const return m_format.foreground(); } else if (m_id == C_PARENTHESES) { return QColor(Qt::red); + } else if (m_id == C_AUTOCOMPLETE) { + return QColor(Qt::darkBlue); } return m_format.foreground(); } @@ -279,6 +281,8 @@ QColor FormatDescription::background() const return QColor(0xb4, 0xee, 0xb4); } else if (m_id == C_PARENTHESES_MISMATCH) { return QColor(Qt::magenta); + } else if (m_id == C_AUTOCOMPLETE) { + return QColor(192, 192, 255); } else if (m_id == C_CURRENT_LINE || m_id == C_SEARCH_SCOPE) { const QPalette palette = QApplication::palette(); const QColor &fg = palette.color(QPalette::Highlight); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index bea97973283..acfde8f79f5 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -329,6 +329,9 @@ public: // parentheses matcher void _q_matchParentheses(); void _q_highlightBlocks(); + void _q_autocompleterHighlight(const QTextCursor &cursor = QTextCursor()); + void updateAnimator(QPointer<TextEditorAnimator> animator, QPainter &painter); + void cancelCurrentAnimations(); void slotSelectionChanged(); void _q_animateUpdate(int position, QPointF lastPos, QRectF rect); void updateCodeFoldingVisible(); @@ -450,7 +453,9 @@ public: bool m_assistRelevantContentAdded; QList<BaseHoverHandler *> m_hoverHandlers; // Not owned - QPointer<TextEditorAnimator> m_animator; + QPointer<TextEditorAnimator> m_bracketsAnimator; + QPointer<TextEditorAnimator> m_autocompleteAnimator; + bool m_animateAutoComplete = true; int m_cursorBlockNumber; int m_blockCount; @@ -738,7 +743,8 @@ void TextEditorWidgetPrivate::ctor(const QSharedPointer<TextDocument> &doc) QObject::connect(&m_scrollBarUpdateTimer, &QTimer::timeout, this, &TextEditorWidgetPrivate::highlightSearchResultsInScrollBar); - m_animator = 0; + m_bracketsAnimator = 0; + m_autocompleteAnimator = 0; slotUpdateExtraAreaWidth(); updateHighlights(); @@ -1104,8 +1110,8 @@ TextEditorWidget *TextEditorWidget::currentTextEditorWidget() void TextEditorWidgetPrivate::editorContentsChange(int position, int charsRemoved, int charsAdded) { - if (m_animator) - m_animator->finish(); + if (m_bracketsAnimator) + m_bracketsAnimator->finish(); m_contentsChanged = true; QTextDocument *doc = q->document(); @@ -2152,6 +2158,13 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) d->m_document->autoIndent(ensureVisible); else if (!previousIndentationString.isEmpty()) ensureVisible.insertText(previousIndentationString); + if (d->m_animateAutoComplete) { + QTextCursor tc = ensureVisible; + tc.movePosition(QTextCursor::EndOfBlock); + tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + tc.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); + d->_q_autocompleterHighlight(tc); + } } setTextCursor(ensureVisible); } @@ -2424,6 +2437,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) cursor.insertText(autoText); //Select the inserted text, to be able to re-indent the inserted text cursor.setPosition(pos, QTextCursor::KeepAnchor); + d->_q_autocompleterHighlight(cursor); } if (!electricChar.isNull() && d->m_autoCompleter->contextAllowsElectricCharacters(cursor)) d->m_document->autoIndent(cursor, electricChar); @@ -4224,11 +4238,8 @@ void TextEditorWidget::paintEvent(QPaintEvent *e) bottom = top + blockBoundingRect(block).height(); } - if (d->m_animator && d->m_animator->isRunning()) { - QTextCursor cursor = textCursor(); - cursor.setPosition(d->m_animator->position()); - d->m_animator->draw(&painter, cursorRect(cursor).topLeft()); - } + d->updateAnimator(d->m_bracketsAnimator, painter); + d->updateAnimator(d->m_autocompleteAnimator, painter); // draw the overlays, but only if we do not have a find scope, otherwise the // view becomes too noisy. @@ -4735,7 +4746,7 @@ void TextEditorWidgetPrivate::updateHighlights() if (m_parenthesesMatchingEnabled && q->hasFocus()) { // Delay update when no matching is displayed yet, to avoid flicker if (q->extraSelections(TextEditorWidget::ParenthesesMatchingSelection).isEmpty() - && m_animator == 0) { + && m_bracketsAnimator == 0) { m_parenthesesMatchingTimer.start(50); } else { // when we uncheck "highlight matching parentheses" @@ -5995,15 +6006,15 @@ void TextEditorWidgetPrivate::_q_matchParentheses() } if (animatePosition >= 0) { - if (m_animator) - m_animator->finish(); // one animation is enough - m_animator = new TextEditorAnimator(this); - m_animator->setPosition(animatePosition); + cancelCurrentAnimations();// one animation is enough + m_bracketsAnimator = new TextEditorAnimator(this); + m_bracketsAnimator->setPosition(animatePosition); QPalette pal; pal.setBrush(QPalette::Text, matchFormat.foreground()); pal.setBrush(QPalette::Base, matchFormat.background()); - m_animator->setData(q->font(), pal, q->document()->characterAt(m_animator->position())); - connect(m_animator.data(), &TextEditorAnimator::updateRequest, + m_bracketsAnimator->setData( + q->font(), pal, q->document()->characterAt(m_bracketsAnimator->position())); + connect(m_bracketsAnimator.data(), &TextEditorAnimator::updateRequest, this, &TextEditorWidgetPrivate::_q_animateUpdate); } if (m_displaySettings.m_highlightMatchingParentheses) @@ -6071,6 +6082,43 @@ void TextEditorWidgetPrivate::_q_highlightBlocks() } } +void TextEditorWidgetPrivate::_q_autocompleterHighlight(const QTextCursor &cursor) +{ + if (!m_animateAutoComplete || q->isReadOnly() || !cursor.hasSelection()) + return; + + const QTextCharFormat &matchFormat + = q->textDocument()->fontSettings().toTextCharFormat(C_AUTOCOMPLETE); + + cancelCurrentAnimations();// one animation is enough + m_autocompleteAnimator = new TextEditorAnimator(this); + m_autocompleteAnimator->setPosition(cursor.selectionStart()); + QPalette pal; + pal.setBrush(QPalette::Text, matchFormat.foreground()); + pal.setBrush(QPalette::Base, matchFormat.background()); + m_autocompleteAnimator->setData(q->font(), pal, cursor.selectedText()); + connect(m_autocompleteAnimator.data(), &TextEditorAnimator::updateRequest, + this, &TextEditorWidgetPrivate::_q_animateUpdate); +} + +void TextEditorWidgetPrivate::updateAnimator(QPointer<TextEditorAnimator> animator, + QPainter &painter) +{ + if (animator && animator->isRunning()) { + QTextCursor cursor = q->textCursor(); + cursor.setPosition(animator->position()); + animator->draw(&painter, q->cursorRect(cursor).topLeft()); + } +} + +void TextEditorWidgetPrivate::cancelCurrentAnimations() +{ + if (m_autocompleteAnimator) + m_autocompleteAnimator->finish(); + if (m_bracketsAnimator) + m_bracketsAnimator->finish(); +} + void TextEditorWidget::changeEvent(QEvent *e) { QPlainTextEdit::changeEvent(e); @@ -6549,6 +6597,7 @@ void TextEditorWidget::setCompletionSettings(const CompletionSettings &completio d->m_autoCompleter->setSurroundWithBracketsEnabled(completionSettings.m_surroundingAutoBrackets); d->m_autoCompleter->setAutoInsertQuotesEnabled(completionSettings.m_autoInsertQuotes); d->m_autoCompleter->setSurroundWithQuotesEnabled(completionSettings.m_surroundingAutoQuotes); + d->m_animateAutoComplete = completionSettings.m_animateAutoComplete; } void TextEditorWidget::setExtraEncodingSettings(const ExtraEncodingSettings &extraEncodingSettings) diff --git a/src/plugins/texteditor/texteditorconstants.cpp b/src/plugins/texteditor/texteditorconstants.cpp index 7325030306d..d670895512a 100644 --- a/src/plugins/texteditor/texteditorconstants.cpp +++ b/src/plugins/texteditor/texteditorconstants.cpp @@ -42,6 +42,7 @@ const char *nameForStyle(TextStyle style) case C_SEARCH_SCOPE: return "SearchScope"; case C_PARENTHESES: return "Parentheses"; case C_PARENTHESES_MISMATCH:return "ParenthesesMismatch"; + case C_AUTOCOMPLETE: return "AutoComplete"; case C_CURRENT_LINE: return "CurrentLine"; case C_CURRENT_LINE_NUMBER: return "CurrentLineNumber"; case C_OCCURRENCES: return "Occurrences"; diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index 0be947fc9a4..8b8180c407d 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -40,6 +40,7 @@ enum TextStyle : quint8 { C_SEARCH_SCOPE, C_PARENTHESES, C_PARENTHESES_MISMATCH, + C_AUTOCOMPLETE, C_CURRENT_LINE, C_CURRENT_LINE_NUMBER, C_OCCURRENCES, diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp index 778ed51ccf4..6a479f9f50e 100644 --- a/src/plugins/texteditor/texteditorsettings.cpp +++ b/src/plugins/texteditor/texteditorsettings.cpp @@ -118,6 +118,9 @@ TextEditorSettings::TextEditorSettings(QObject *parent) formatDescr.emplace_back(C_PARENTHESES_MISMATCH, tr("Mismatched Parentheses"), tr("Displayed when mismatched parentheses, " "square brackets, or curly brackets are found.")); + formatDescr.emplace_back(C_AUTOCOMPLETE, tr("Auto Complete"), + tr("Displayed when a character is automatically inserted " + "like brackets or quotes.")); formatDescr.emplace_back(C_CURRENT_LINE, tr("Current Line"), tr("Line where the cursor is placed in."), FormatDescription::ShowBackgroundControl); |