From 1c4fc0d7dd0fd1834b2cadd6afc931067b47d333 Mon Sep 17 00:00:00 2001
From: mae <qt-info@nokia.com>
Date: Tue, 15 Sep 2009 17:04:17 +0200
Subject: [PATCH] preliminary auto parentheses support

---
 src/plugins/texteditor/basetexteditor.cpp     | 90 ++++++++++++++-----
 .../texteditor/behaviorsettingspage.cpp       |  2 +
 .../texteditor/behaviorsettingspage.ui        |  9 +-
 src/plugins/texteditor/tabsettings.cpp        |  5 ++
 src/plugins/texteditor/tabsettings.h          |  1 +
 5 files changed, 86 insertions(+), 21 deletions(-)

diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 905c911b4ab..3572bf446d0 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -888,18 +888,31 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
         if (d->m_inBlockSelectionMode)
             cursor.clearSelection();
         const TabSettings &ts = d->m_document->tabSettings();
+        cursor.beginEditBlock();
+
+        if (ts.m_autoParentheses
+            && characterAt(cursor.position()) == QLatin1Char('}')) {
+            int pos = cursor.position();
+            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);
+        }
+
         if (ts.m_autoIndent) {
-            cursor.beginEditBlock();
             cursor.insertBlock();
             indent(document(), cursor, QChar::Null);
-            cursor.endEditBlock();
         } else {
-            cursor.beginEditBlock();
             QString previousBlockText = cursor.block().text();
             cursor.insertBlock();
             cursor.insertText(ts.indentationString(previousBlockText));
-            cursor.endEditBlock();
         }
+        cursor.endEditBlock();
         e->accept();
         setTextCursor(cursor);
         return;
@@ -1029,21 +1042,6 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
         break;
 
     default:
-        if (! ro && d->m_document->tabSettings().m_autoIndent
-            && ! e->text().isEmpty() && isElectricCharacter(e->text().at(0))) {
-            QTextCursor cursor = textCursor();
-            const QString text = e->text();
-            cursor.insertText(text);
-            indent(document(), cursor, text.at(0));
-#if 0
-            TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(document()->documentLayout());
-            QTC_ASSERT(documentLayout, return);
-            documentLayout->requestUpdate(); // a bit drastic
-            e->accept();
-#endif
-            setTextCursor(cursor);
-            return;
-        }
         break;
     }
 
@@ -1055,7 +1053,59 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
         }
     }
 
-    QPlainTextEdit::keyPressEvent(e);
+    if (ro || e->text().isEmpty() || !e->text().at(0).isPrint()) {
+        QPlainTextEdit::keyPressEvent(e);
+    } else {
+        QTextCursor cursor = textCursor();
+        QString text = e->text();
+        QString autoText;
+        if (d->m_document->tabSettings().m_autoParentheses) {
+            foreach(QChar c, text) {
+                QChar close;
+                if (c == QLatin1Char('{'))
+                    close = QLatin1Char('}');
+                else if (c == QLatin1Char('('))
+                    close = QLatin1Char(')');
+                else if (c == QLatin1Char('['))
+                    close = QLatin1Char(']');
+                if (!close.isNull())
+                    autoText += close;
+            }
+
+            QChar first = text.at(0);
+            if (first == QLatin1Char(')')
+                || first == QLatin1Char('}')
+                || first == QLatin1Char(']')) {
+                if (first == characterAt(cursor.position())) {
+                    int pos = cursor.position();
+                    cursor.setPosition(pos+1);
+                    cursor.setPosition(pos, QTextCursor::KeepAnchor);
+                }
+            }
+        }
+        QChar electricChar;
+        if (d->m_document->tabSettings().m_autoIndent) {
+            foreach(QChar c, text) {
+                if (isElectricCharacter(c)) {
+                    electricChar = c;
+                    break;
+                }
+            }
+        }
+        if (!electricChar.isNull())
+            cursor.beginEditBlock();
+        cursor.insertText(text);
+        if (!autoText.isEmpty()) {
+            int pos = cursor.position();
+            cursor.insertText(autoText);
+            cursor.setPosition(pos);
+        }
+        if (!electricChar.isNull()) {
+            indent(document(), cursor, electricChar);
+            cursor.endEditBlock();
+        }
+        setTextCursor(cursor);
+    }
 
 skip_event:
     if (!ro && e->key() == Qt::Key_Delete && d->m_parenthesesMatchingEnabled)
diff --git a/src/plugins/texteditor/behaviorsettingspage.cpp b/src/plugins/texteditor/behaviorsettingspage.cpp
index ed013c6b610..a8fa108b7af 100644
--- a/src/plugins/texteditor/behaviorsettingspage.cpp
+++ b/src/plugins/texteditor/behaviorsettingspage.cpp
@@ -130,6 +130,7 @@ void BehaviorSettingsPage::settingsFromUI(TabSettings &tabSettings,
 {
     tabSettings.m_spacesForTabs = m_d->m_page.insertSpaces->isChecked();
     tabSettings.m_autoIndent = m_d->m_page.autoIndent->isChecked();
+    tabSettings.m_autoParentheses= m_d->m_page.autoParentheses->isChecked();
     tabSettings.m_smartBackspace = m_d->m_page.smartBackspace->isChecked();
     tabSettings.m_tabSize = m_d->m_page.tabSize->value();
     tabSettings.m_indentSize = m_d->m_page.indentSize->value();
@@ -146,6 +147,7 @@ void BehaviorSettingsPage::settingsToUI()
     const TabSettings &tabSettings = m_d->m_tabSettings;
     m_d->m_page.insertSpaces->setChecked(tabSettings.m_spacesForTabs);
     m_d->m_page.autoIndent->setChecked(tabSettings.m_autoIndent);
+    m_d->m_page.autoParentheses->setChecked(tabSettings.m_autoParentheses);
     m_d->m_page.smartBackspace->setChecked(tabSettings.m_smartBackspace);
     m_d->m_page.tabSize->setValue(tabSettings.m_tabSize);
     m_d->m_page.indentSize->setValue(tabSettings.m_indentSize);
diff --git a/src/plugins/texteditor/behaviorsettingspage.ui b/src/plugins/texteditor/behaviorsettingspage.ui
index c20e2aaad12..a245afcebaf 100644
--- a/src/plugins/texteditor/behaviorsettingspage.ui
+++ b/src/plugins/texteditor/behaviorsettingspage.ui
@@ -14,7 +14,7 @@
    <item>
     <widget class="QGroupBox" name="groupBoxTabAndIndentSettings">
      <property name="title">
-      <string>Tabs and Indentation</string>
+      <string>Tabs, Indentation, and Parentheses</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout">
       <item>
@@ -133,6 +133,13 @@
           </property>
          </spacer>
         </item>
+        <item row="3" column="0">
+         <widget class="QCheckBox" name="autoParentheses">
+          <property name="text">
+           <string>Enable automatic &amp;parentheses</string>
+          </property>
+         </widget>
+        </item>
        </layout>
       </item>
       <item>
diff --git a/src/plugins/texteditor/tabsettings.cpp b/src/plugins/texteditor/tabsettings.cpp
index 393434d9085..7be914b3171 100644
--- a/src/plugins/texteditor/tabsettings.cpp
+++ b/src/plugins/texteditor/tabsettings.cpp
@@ -38,6 +38,7 @@
 static const char *spacesForTabsKey = "SpacesForTabs";
 static const char *smartBackspaceKey = "SmartBackspace";
 static const char *autoIndentKey = "AutoIndent";
+static const char *autoParenthesesKey= "AutoParentheses";
 static const char *tabSizeKey = "TabSize";
 static const char *indentSizeKey = "IndentSize";
 static const char *tabKeyBehaviorKey = "TabKeyBehavior";
@@ -48,6 +49,7 @@ namespace TextEditor {
 TabSettings::TabSettings() :
     m_spacesForTabs(true),
     m_autoIndent(true),
+    m_autoParentheses(true),
     m_smartBackspace(false),
     m_tabSize(8),
     m_indentSize(4),
@@ -63,6 +65,7 @@ void TabSettings::toSettings(const QString &category, QSettings *s) const
     s->beginGroup(group);
     s->setValue(QLatin1String(spacesForTabsKey),  m_spacesForTabs);
     s->setValue(QLatin1String(autoIndentKey), m_autoIndent);
+    s->setValue(QLatin1String(autoParenthesesKey), m_autoParentheses);
     s->setValue(QLatin1String(smartBackspaceKey), m_smartBackspace);
     s->setValue(QLatin1String(tabSizeKey), m_tabSize);
     s->setValue(QLatin1String(indentSizeKey), m_indentSize);
@@ -81,6 +84,7 @@ void TabSettings::fromSettings(const QString &category, const QSettings *s)
 
     m_spacesForTabs   = s->value(group + QLatin1String(spacesForTabsKey), m_spacesForTabs).toBool();
     m_autoIndent      = s->value(group + QLatin1String(autoIndentKey), m_autoIndent).toBool();
+    m_autoParentheses = s->value(group + QLatin1String(autoParenthesesKey), m_autoParentheses).toBool();
     m_smartBackspace  = s->value(group + QLatin1String(smartBackspaceKey), m_smartBackspace).toBool();
     m_tabSize         = s->value(group + QLatin1String(tabSizeKey), m_tabSize).toInt();
     m_indentSize      = s->value(group + QLatin1String(indentSizeKey), m_indentSize).toInt();
@@ -259,6 +263,7 @@ bool TabSettings::equals(const TabSettings &ts) const
 {
     return m_spacesForTabs == ts.m_spacesForTabs
         && m_autoIndent == ts.m_autoIndent
+        && m_autoParentheses== ts.m_autoParentheses
         && m_smartBackspace == ts.m_smartBackspace
         && m_tabSize == ts.m_tabSize
         && m_indentSize == ts.m_indentSize
diff --git a/src/plugins/texteditor/tabsettings.h b/src/plugins/texteditor/tabsettings.h
index f26e0bb5ad9..64bdf89b0da 100644
--- a/src/plugins/texteditor/tabsettings.h
+++ b/src/plugins/texteditor/tabsettings.h
@@ -74,6 +74,7 @@ struct TEXTEDITOR_EXPORT TabSettings
 
     bool m_spacesForTabs;
     bool m_autoIndent;
+    bool m_autoParentheses;
     bool m_smartBackspace;
     int m_tabSize;
     int m_indentSize;
-- 
GitLab