From 3f1b45b0579e7f1c7c2c88f12a1ef3414b9b2061 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= <thorbjorn.lindeijer@nokia.com>
Date: Wed, 9 Dec 2009 19:08:14 +0100
Subject: [PATCH] Implemented first-letter case-sensitive for completion as
 default

By default now only the first letter is case-sensitive. It is still
possible to choose full or no case-sensitivity as well.

Task-number: QTCREATORBUG-236
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
---
 .../cpptools/completionsettingspage.cpp       | 34 ++++++--
 src/plugins/cpptools/completionsettingspage.h |  6 +-
 .../cpptools/completionsettingspage.ui        | 80 ++++++++++++++++---
 src/plugins/cpptools/cppcodecompletion.cpp    | 21 +++--
 src/plugins/cpptools/cppcodecompletion.h      | 12 ++-
 src/plugins/cpptools/cpptoolsplugin.cpp       |  6 +-
 6 files changed, 128 insertions(+), 31 deletions(-)

diff --git a/src/plugins/cpptools/completionsettingspage.cpp b/src/plugins/cpptools/completionsettingspage.cpp
index 8c5e7ba2a49..276111c947e 100644
--- a/src/plugins/cpptools/completionsettingspage.cpp
+++ b/src/plugins/cpptools/completionsettingspage.cpp
@@ -28,7 +28,6 @@
 **************************************************************************/
 
 #include "completionsettingspage.h"
-#include "cppcodecompletion.h"
 #include "ui_completionsettingspage.h"
 
 #include <coreplugin/icore.h>
@@ -63,7 +62,6 @@ QString CompletionSettingsPage::trName() const
 
 QString CompletionSettingsPage::category() const
 {
-
     return QLatin1String(TextEditor::Constants::TEXT_EDITOR_SETTINGS_CATEGORY);
 }
 
@@ -77,11 +75,24 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
     QWidget *w = new QWidget(parent);
     m_page->setupUi(w);
 
-    m_page->caseSensitive->setChecked(m_completion->caseSensitivity() == Qt::CaseSensitive);
+    int caseSensitivityIndex;
+    switch (m_completion->caseSensitivity()) {
+    case CppCodeCompletion::CaseSensitive:
+        caseSensitivityIndex = 0;
+        break;
+    case CppCodeCompletion::CaseInsensitive:
+        caseSensitivityIndex = 1;
+        break;
+    case CppCodeCompletion::FirstLetterCaseSensitive:
+        caseSensitivityIndex = 2;
+        break;
+    }
+
+    m_page->caseSensitivity->setCurrentIndex(caseSensitivityIndex);
     m_page->autoInsertBrackets->setChecked(m_completion->autoInsertBrackets());
     m_page->partiallyComplete->setChecked(m_completion->isPartialCompletionEnabled());
     if (m_searchKeywords.isEmpty()) {
-        QTextStream(&m_searchKeywords) << m_page->caseSensitive->text()
+        QTextStream(&m_searchKeywords) << m_page->caseSensitivityLabel->text()
                 << ' ' << m_page->autoInsertBrackets->text()
                 << ' ' << m_page->partiallyComplete->text();
         m_searchKeywords.remove(QLatin1Char('&'));
@@ -91,8 +102,7 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
 
 void CompletionSettingsPage::apply()
 {
-    m_completion->setCaseSensitivity(
-            m_page->caseSensitive->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
+    m_completion->setCaseSensitivity(caseSensitivity());
     m_completion->setAutoInsertBrackets(m_page->autoInsertBrackets->isChecked());
     m_completion->setPartialCompletionEnabled(m_page->partiallyComplete->isChecked());
 }
@@ -101,3 +111,15 @@ bool CompletionSettingsPage::matches(const QString &s) const
 {
     return m_searchKeywords.contains(s, Qt::CaseInsensitive);
 }
+
+CppCodeCompletion::CaseSensitivity CompletionSettingsPage::caseSensitivity() const
+{
+    switch (m_page->caseSensitivity->currentIndex()) {
+    case 0: // Full
+        return CppCodeCompletion::CaseSensitive;
+    case 1: // None
+        return CppCodeCompletion::CaseInsensitive;
+    default: // First letter
+        return CppCodeCompletion::FirstLetterCaseSensitive;
+    }
+}
diff --git a/src/plugins/cpptools/completionsettingspage.h b/src/plugins/cpptools/completionsettingspage.h
index 0123b3885ef..fe210b12078 100644
--- a/src/plugins/cpptools/completionsettingspage.h
+++ b/src/plugins/cpptools/completionsettingspage.h
@@ -32,6 +32,8 @@
 
 #include <coreplugin/dialogs/ioptionspage.h>
 
+#include "cppcodecompletion.h"
+
 QT_BEGIN_NAMESPACE
 class Ui_CompletionSettingsPage;
 QT_END_NAMESPACE
@@ -39,8 +41,6 @@ QT_END_NAMESPACE
 namespace CppTools {
 namespace Internal {
 
-class CppCodeCompletion;
-
 class CompletionSettingsPage : public Core::IOptionsPage
 {
     Q_OBJECT
@@ -60,6 +60,8 @@ public:
     virtual bool matches(const QString &) const;
 
 private:
+    CppCodeCompletion::CaseSensitivity caseSensitivity() const;
+
     CppCodeCompletion *m_completion;
     Ui_CompletionSettingsPage *m_page;
     QString m_searchKeywords;
diff --git a/src/plugins/cpptools/completionsettingspage.ui b/src/plugins/cpptools/completionsettingspage.ui
index c00b8aabd3d..a884752910a 100644
--- a/src/plugins/cpptools/completionsettingspage.ui
+++ b/src/plugins/cpptools/completionsettingspage.ui
@@ -13,19 +13,77 @@
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Behavior</string>
+     </property>
      <layout class="QVBoxLayout" name="verticalLayout_2">
       <item>
-       <widget class="QCheckBox" name="caseSensitive">
-        <property name="toolTip">
-         <string>Do a case-sensitive match for completion items.</string>
-        </property>
-        <property name="text">
-         <string>&amp;Case-sensitive completion</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QLabel" name="caseSensitivityLabel">
+          <property name="text">
+           <string>&amp;Case-sensitivity:</string>
+          </property>
+          <property name="buddy">
+           <cstring>caseSensitivity</cstring>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Maximum</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QComboBox" name="caseSensitivity">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <item>
+           <property name="text">
+            <string>Full</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>None</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>First letter</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>0</width>
+            <height>0</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
       </item>
       <item>
        <widget class="QCheckBox" name="autoInsertBrackets">
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 14764970b13..2a714dbab50 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -476,7 +476,7 @@ CppCodeCompletion::CppCodeCompletion(CppModelManager *manager)
       m_manager(manager),
       m_editor(0),
       m_startPosition(-1),
-      m_caseSensitivity(Qt::CaseSensitive),
+      m_caseSensitivity(FirstLetterCaseSensitive),
       m_autoInsertBrackets(true),
       m_partialCompletionEnabled(true),
       m_forcedCompletion(false),
@@ -490,12 +490,12 @@ QIcon CppCodeCompletion::iconForSymbol(Symbol *symbol) const
     return m_icons.iconForSymbol(symbol);
 }
 
-Qt::CaseSensitivity CppCodeCompletion::caseSensitivity() const
+CppCodeCompletion::CaseSensitivity CppCodeCompletion::caseSensitivity() const
 {
     return m_caseSensitivity;
 }
 
-void CppCodeCompletion::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
+void CppCodeCompletion::setCaseSensitivity(CaseSensitivity caseSensitivity)
 {
     m_caseSensitivity = caseSensitivity;
 }
@@ -1438,20 +1438,29 @@ void CppCodeCompletion::completions(QList<TextEditor::CompletionItem> *completio
              *
              * Meaning it allows any sequence of lower-case characters to preceed an
              * upper-case character. So for example gAC matches getActionController.
+             *
+             * It also implements the first-letter-only case sensitivity.
              */
             QString keyRegExp;
             keyRegExp += QLatin1Char('^');
             bool first = true;
             foreach (const QChar &c, key) {
-                if (c.isUpper() && !first) {
+                if (c.isUpper() && !first)
                     keyRegExp += QLatin1String("[a-z0-9_]*");
-                    keyRegExp += c;
+
+                if (m_caseSensitivity == FirstLetterCaseSensitive && !first) {
+                    keyRegExp += QLatin1Char('[');
+                    keyRegExp += QRegExp::escape(c.toLower());
+                    keyRegExp += QRegExp::escape(c.toUpper());
+                    keyRegExp += QLatin1Char(']');
                 } else {
                     keyRegExp += QRegExp::escape(c);
                 }
+
                 first = false;
             }
-            const QRegExp regExp(keyRegExp, m_caseSensitivity);
+            const QRegExp regExp(keyRegExp, (m_caseSensitivity == CaseInsensitive)
+                                 ? Qt::CaseInsensitive : Qt::CaseSensitive);
 
             foreach (TextEditor::CompletionItem item, m_completions) {
                 if (regExp.indexIn(item.text) == 0) {
diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h
index 0b0bb162368..a83e29ebfc1 100644
--- a/src/plugins/cpptools/cppcodecompletion.h
+++ b/src/plugins/cpptools/cppcodecompletion.h
@@ -76,8 +76,14 @@ public:
 
     QIcon iconForSymbol(CPlusPlus::Symbol *symbol) const;
 
-    Qt::CaseSensitivity caseSensitivity() const;
-    void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
+    enum CaseSensitivity {
+        CaseInsensitive,
+        CaseSensitive,
+        FirstLetterCaseSensitive
+    };
+
+    CaseSensitivity caseSensitivity() const;
+    void setCaseSensitivity(CaseSensitivity caseSensitivity);
 
     bool autoInsertBrackets() const;
     void setAutoInsertBrackets(bool autoInsertBrackets);
@@ -136,7 +142,7 @@ private:
     TextEditor::ITextEditable *m_editor;
     int m_startPosition;     // Position of the cursor from which completion started
 
-    Qt::CaseSensitivity m_caseSensitivity;
+    CaseSensitivity m_caseSensitivity;
     bool m_autoInsertBrackets;
     bool m_partialCompletionEnabled;
     bool m_forcedCompletion;
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index 354ecf63544..5f5e0011a71 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -139,8 +139,8 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
     QSettings *settings = Core::ICore::instance()->settings();
     settings->beginGroup(QLatin1String("CppTools"));
     settings->beginGroup(QLatin1String("Completion"));
-    const bool caseSensitive = settings->value(QLatin1String("CaseSensitive"), true).toBool();
-    m_completion->setCaseSensitivity(caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
+    const int caseSensitivity = settings->value(QLatin1String("CaseSensitivity"), m_completion->caseSensitivity()).toInt();
+    m_completion->setCaseSensitivity((CppCodeCompletion::CaseSensitivity) caseSensitivity);
     m_completion->setAutoInsertBrackets(settings->value(QLatin1String("AutoInsertBraces"), true).toBool());
     m_completion->setPartialCompletionEnabled(settings->value(QLatin1String("PartiallyComplete"), true).toBool());
     settings->endGroup();
@@ -169,7 +169,7 @@ void CppToolsPlugin::shutdown()
     QSettings *settings = Core::ICore::instance()->settings();
     settings->beginGroup(QLatin1String("CppTools"));
     settings->beginGroup(QLatin1String("Completion"));
-    settings->setValue(QLatin1String("CaseSensitive"), m_completion->caseSensitivity() == Qt::CaseSensitive);
+    settings->setValue(QLatin1String("CaseSensitivity"), (int) m_completion->caseSensitivity());
     settings->setValue(QLatin1String("AutoInsertBraces"), m_completion->autoInsertBrackets());
     settings->setValue(QLatin1String("PartiallyComplete"), m_completion->isPartialCompletionEnabled());
     settings->endGroup();
-- 
GitLab