From 8fe25d0a4a1f61d0071ff9f10bb26204354da58e Mon Sep 17 00:00:00 2001
From: Nikolai Kosjar <nikolai.kosjar@digia.com>
Date: Tue, 15 Jan 2013 14:26:24 +0100
Subject: [PATCH] C++: Add settings dialog for pointer declaration formatting

The dialog is at Tools > Options > C++ > Code Style > Edit... > Pointers
and References.

Currently the settings are referenced when applying the following
QuickFixes:
 - Adapting function signature in declaration/definition
   (FunctionDeclDefLink)
 - Inserting declaration from definition (InsertDeclOperation)
 - Inserting definition from declaration (InsertDefOperation)
 - Extracting a function (ExtractFunctionOperation)
 - Add Local Declaration (AddLocalDeclarationOp::Operation)

In these cases the code style of the current project is used. If there
is no current project open, the current global code style is used.

Task-number: QTCREATORBUG-6169

Change-Id: I3e4e502b3103f7f754ac9b39594ad461d89d9304
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
---
 .../cppeditor/cppfunctiondecldeflink.cpp      |   8 +-
 src/plugins/cppeditor/cppinsertdecldef.cpp    |   7 +-
 src/plugins/cppeditor/cppquickfixes.cpp       |  27 ++---
 src/plugins/cpptools/cppcodestylesettings.cpp |  89 ++++++++++++++-
 src/plugins/cpptools/cppcodestylesettings.h   |  23 ++++
 .../cpptools/cppcodestylesettingspage.cpp     | 102 ++++++++++++++++--
 .../cpptools/cppcodestylesettingspage.ui      |  82 +++++++++++++-
 7 files changed, 308 insertions(+), 30 deletions(-)

diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
index 46c66466ba4..8cf83fd6ae1 100644
--- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
+++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
@@ -40,6 +40,7 @@
 #include <cplusplus/TranslationUnit.h>
 #include <cplusplus/LookupContext.h>
 #include <cplusplus/Overview.h>
+#include <cpptools/cppcodestylesettings.h>
 #include <cpptools/cpplocalsymbols.h>
 #include <cpptools/cpprefactoringchanges.h>
 #include <cpptools/symbolfinder.h>
@@ -590,7 +591,10 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ
     if (!newFunction)
         return changes;
 
-    Overview overview;
+    const Overview overviewFromCurrentProjectStyle
+        = CppCodeStyleSettings::currentProjectCodeStyleOverview();
+
+    Overview overview = overviewFromCurrentProjectStyle;
     overview.showReturnTypes = true;
     overview.showTemplateParameters = true;
     overview.showArgumentNames = true;
@@ -664,7 +668,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ
         UseMinimalNames q(targetCoN);
         env.enter(&q);
         Control *control = sourceContext.control().data();
-        Overview overview;
+        Overview overview = overviewFromCurrentProjectStyle;
 
         // make a easy to access list of the target parameter declarations
         QVarLengthArray<ParameterDeclarationAST *, 10> targetParameterDecls;
diff --git a/src/plugins/cppeditor/cppinsertdecldef.cpp b/src/plugins/cppeditor/cppinsertdecldef.cpp
index b715f5b2db9..f1616454d7e 100644
--- a/src/plugins/cppeditor/cppinsertdecldef.cpp
+++ b/src/plugins/cppeditor/cppinsertdecldef.cpp
@@ -37,6 +37,7 @@
 #include <cplusplus/Overview.h>
 #include <cplusplus/ASTVisitor.h>
 #include <cpptools/insertionpointlocator.h>
+#include <cpptools/cppcodestylesettings.h>
 #include <cpptools/cpprefactoringchanges.h>
 #include <cpptools/cpptoolsreuse.h>
 
@@ -202,7 +203,7 @@ void DeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperation
 
 QString InsertDeclOperation::generateDeclaration(Function *function)
 {
-    Overview oo;
+    Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
     oo.showFunctionSignatures = true;
     oo.showReturnTypes = true;
     oo.showArgumentNames = true;
@@ -238,7 +239,7 @@ public:
         CppRefactoringChanges refactoring(snapshot());
         CppRefactoringFilePtr targetFile = refactoring.file(m_loc.fileName());
 
-        Overview oo;
+        Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
         oo.showFunctionSignatures = true;
         oo.showReturnTypes = true;
         oo.showArgumentNames = true;
@@ -361,7 +362,7 @@ public:
         UseMinimalNames subs(targetCoN);
         env.enter(&subs);
 
-        Overview printer;
+        Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview();
         Control *control = assistInterface()->context().control().data();
         QString funcDef;
         QString funcDecl; // We generate a declaration only in the case of a member function.
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index b53457aaa90..3b72573c86e 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -55,6 +55,7 @@
 #include <cplusplus/TypeOfExpression.h>
 #include <cpptools/ModelManagerInterface.h>
 #include <cplusplus/CppRewriter.h>
+#include <cpptools/cppcodestylesettings.h>
 #include <cpptools/cpptoolsconstants.h>
 #include <cpptools/cpprefactoringchanges.h>
 #include <cpptools/insertionpointlocator.h>
@@ -1665,7 +1666,8 @@ public:
                         }
 
                         if (! decl) {
-                            result.append(QuickFixOperation::Ptr(new Operation(interface, index, binary)));
+                            result.append(QuickFixOperation::Ptr(
+                                new Operation(interface, index, binary, nameAST)));
                             return;
                         }
                     }
@@ -1678,9 +1680,13 @@ private:
     class Operation: public CppQuickFixOperation
     {
     public:
-        Operation(const CppQuickFixInterface &interface, int priority, BinaryExpressionAST *binaryAST)
+        Operation(const CppQuickFixInterface &interface,
+                  int priority,
+                  const BinaryExpressionAST *binaryAST,
+                  const SimpleNameAST *simpleNameAST)
             : CppQuickFixOperation(interface, priority)
             , binaryAST(binaryAST)
+            , simpleNameAST(simpleNameAST)
         {
             setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration"));
         }
@@ -1700,7 +1706,6 @@ private:
                                      TypeOfExpression::Preprocess);
 
             if (! result.isEmpty()) {
-
                 SubstitutionEnvironment env;
                 env.setContext(assistInterface()->context());
                 env.switchScope(result.first().scope());
@@ -1713,16 +1718,13 @@ private:
                 Control *control = assistInterface()->context().control().data();
                 FullySpecifiedType tn = rewriteType(result.first().type(), &env, control);
 
-                Overview oo;
-                QString ty = oo.prettyType(tn);
+                Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
+                QString ty = oo.prettyType(tn, simpleNameAST->name);
                 if (! ty.isEmpty()) {
-                    const QChar ch = ty.at(ty.size() - 1);
-
-                    if (ch.isLetterOrNumber() || ch == QLatin1Char(' ') || ch == QLatin1Char('>'))
-                        ty += QLatin1Char(' ');
-
                     Utils::ChangeSet changes;
-                    changes.insert(currentFile->startOf(binaryAST), ty);
+                    changes.replace(currentFile->startOf(binaryAST),
+                                    currentFile->endOf(simpleNameAST),
+                                    ty);
                     currentFile->setChangeSet(changes);
                     currentFile->apply();
                 }
@@ -1730,7 +1732,8 @@ private:
         }
 
     private:
-        BinaryExpressionAST *binaryAST;
+        const BinaryExpressionAST *binaryAST;
+        const SimpleNameAST *simpleNameAST;
     };
 };
 
diff --git a/src/plugins/cpptools/cppcodestylesettings.cpp b/src/plugins/cpptools/cppcodestylesettings.cpp
index 6295a9f22d2..83655b3ce75 100644
--- a/src/plugins/cpptools/cppcodestylesettings.cpp
+++ b/src/plugins/cpptools/cppcodestylesettings.cpp
@@ -29,6 +29,19 @@
 
 #include "cppcodestylesettings.h"
 
+#include <cpptools/cppcodestylepreferences.h>
+#include <cpptools/cppcodestylesettings.h>
+#include <cpptools/cpptoolsconstants.h>
+#include <cpptools/cpptoolssettings.h>
+
+#include <projectexplorer/editorconfiguration.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectexplorer.h>
+
+#include <cppcodestylepreferencesfactory.h>
+
+#include <utils/qtcassert.h>
+
 #include <utils/settingsutils.h>
 
 static const char groupPostfix[] = "IndentSettings";
@@ -46,6 +59,10 @@ static const char indentSwitchLabelsKey[] = "IndentSwitchLabels";
 static const char indentStatementsRelativeToSwitchLabelsKey[] = "IndentStatementsRelativeToSwitchLabels";
 static const char indentBlocksRelativeToSwitchLabelsKey[] = "IndentBlocksRelativeToSwitchLabels";
 static const char indentControlFlowRelativeToSwitchLabelsKey[] = "IndentControlFlowRelativeToSwitchLabels";
+static const char bindStarToIdentifierKey[] = "BindStarToIdentifier";
+static const char bindStarToTypeNameKey[] = "BindStarToTypeName";
+static const char bindStarToLeftSpecifierKey[] = "BindStarToLeftSpecifier";
+static const char bindStarToRightSpecifierKey[] = "BindStarToRightSpecifier";
 static const char extraPaddingForConditionsIfConfusingAlignKey[] = "ExtraPaddingForConditionsIfConfusingAlign";
 static const char alignAssignmentsKey[] = "AlignAssignments";
 
@@ -68,6 +85,10 @@ CppCodeStyleSettings::CppCodeStyleSettings() :
   , indentStatementsRelativeToSwitchLabels(true)
   , indentBlocksRelativeToSwitchLabels(false)
   , indentControlFlowRelativeToSwitchLabels(true)
+  , bindStarToIdentifier(true)
+  , bindStarToTypeName(false)
+  , bindStarToLeftSpecifier(false)
+  , bindStarToRightSpecifier(false)
   , extraPaddingForConditionsIfConfusingAlign(true)
   , alignAssignments(false)
 {
@@ -100,6 +121,10 @@ void CppCodeStyleSettings::toMap(const QString &prefix, QVariantMap *map) const
     map->insert(prefix + QLatin1String(indentStatementsRelativeToSwitchLabelsKey), indentStatementsRelativeToSwitchLabels);
     map->insert(prefix + QLatin1String(indentBlocksRelativeToSwitchLabelsKey), indentBlocksRelativeToSwitchLabels);
     map->insert(prefix + QLatin1String(indentControlFlowRelativeToSwitchLabelsKey), indentControlFlowRelativeToSwitchLabels);
+    map->insert(prefix + QLatin1String(bindStarToIdentifierKey), bindStarToIdentifier);
+    map->insert(prefix + QLatin1String(bindStarToTypeNameKey), bindStarToTypeName);
+    map->insert(prefix + QLatin1String(bindStarToLeftSpecifierKey), bindStarToLeftSpecifier);
+    map->insert(prefix + QLatin1String(bindStarToRightSpecifierKey), bindStarToRightSpecifier);
     map->insert(prefix + QLatin1String(extraPaddingForConditionsIfConfusingAlignKey), extraPaddingForConditionsIfConfusingAlign);
     map->insert(prefix + QLatin1String(alignAssignmentsKey), alignAssignments);
 }
@@ -134,6 +159,14 @@ void CppCodeStyleSettings::fromMap(const QString &prefix, const QVariantMap &map
                                 indentBlocksRelativeToSwitchLabels).toBool();
     indentControlFlowRelativeToSwitchLabels = map.value(prefix + QLatin1String(indentControlFlowRelativeToSwitchLabelsKey),
                                 indentControlFlowRelativeToSwitchLabels).toBool();
+    bindStarToIdentifier = map.value(prefix + QLatin1String(bindStarToIdentifierKey),
+                                bindStarToIdentifier).toBool();
+    bindStarToTypeName = map.value(prefix + QLatin1String(bindStarToTypeNameKey),
+                                bindStarToTypeName).toBool();
+    bindStarToLeftSpecifier = map.value(prefix + QLatin1String(bindStarToLeftSpecifierKey),
+                                bindStarToLeftSpecifier).toBool();
+    bindStarToRightSpecifier = map.value(prefix + QLatin1String(bindStarToRightSpecifierKey),
+                                bindStarToRightSpecifier).toBool();
     extraPaddingForConditionsIfConfusingAlign = map.value(prefix + QLatin1String(extraPaddingForConditionsIfConfusingAlignKey),
                                 extraPaddingForConditionsIfConfusingAlign).toBool();
     alignAssignments = map.value(prefix + QLatin1String(alignAssignmentsKey),
@@ -156,7 +189,61 @@ bool CppCodeStyleSettings::equals(const CppCodeStyleSettings &rhs) const
            && indentStatementsRelativeToSwitchLabels == rhs.indentStatementsRelativeToSwitchLabels
            && indentBlocksRelativeToSwitchLabels == rhs.indentBlocksRelativeToSwitchLabels
            && indentControlFlowRelativeToSwitchLabels == rhs.indentControlFlowRelativeToSwitchLabels
+           && bindStarToIdentifier == rhs.bindStarToIdentifier
+           && bindStarToTypeName == rhs.bindStarToTypeName
+           && bindStarToLeftSpecifier == rhs.bindStarToLeftSpecifier
+           && bindStarToRightSpecifier == rhs.bindStarToRightSpecifier
            && extraPaddingForConditionsIfConfusingAlign == rhs.extraPaddingForConditionsIfConfusingAlign
-           && alignAssignments == rhs.alignAssignments;
+            && alignAssignments == rhs.alignAssignments;
+}
+
+static void configureOverviewWithCodeStyleSettings(CPlusPlus::Overview &overview,
+                                                   const CppCodeStyleSettings &settings)
+{
+    overview.starBindFlags = CPlusPlus::Overview::StarBindFlags(0);
+    if (settings.bindStarToIdentifier)
+        overview.starBindFlags |= CPlusPlus::Overview::BindToIdentifier;
+    if (settings.bindStarToTypeName)
+        overview.starBindFlags |= CPlusPlus::Overview::BindToTypeName;
+    if (settings.bindStarToLeftSpecifier)
+        overview.starBindFlags |= CPlusPlus::Overview::BindToLeftSpecifier;
+    if (settings.bindStarToRightSpecifier)
+        overview.starBindFlags |= CPlusPlus::Overview::BindToRightSpecifier;
+}
+
+CPlusPlus::Overview CppCodeStyleSettings::currentProjectCodeStyleOverview()
+{
+    ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::currentProject();
+    if (! project)
+        return currentGlobalCodeStyleOverview();
+
+    ProjectExplorer::EditorConfiguration *editorConfiguration = project->editorConfiguration();
+    QTC_ASSERT(editorConfiguration, return currentGlobalCodeStyleOverview());
+
+    TextEditor::ICodeStylePreferences *codeStylePreferences
+        = editorConfiguration->codeStyle(Constants::CPP_SETTINGS_ID);
+    QTC_ASSERT(codeStylePreferences, return currentGlobalCodeStyleOverview());
+
+    CppCodeStylePreferences *cppCodeStylePreferences
+        = dynamic_cast<CppCodeStylePreferences *>(codeStylePreferences);
+    QTC_ASSERT(cppCodeStylePreferences, return currentGlobalCodeStyleOverview());
+
+    CppCodeStyleSettings settings = cppCodeStylePreferences->currentCodeStyleSettings();
+
+    CPlusPlus::Overview overview;
+    configureOverviewWithCodeStyleSettings(overview, settings);
+    return overview;
 }
 
+CPlusPlus::Overview CppCodeStyleSettings::currentGlobalCodeStyleOverview()
+{
+    CPlusPlus::Overview overview;
+
+    CppCodeStylePreferences *cppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle();
+    QTC_ASSERT(cppCodeStylePreferences, return overview);
+
+    CppCodeStyleSettings settings = cppCodeStylePreferences->currentCodeStyleSettings();
+
+    configureOverviewWithCodeStyleSettings(overview, settings);
+    return overview;
+}
diff --git a/src/plugins/cpptools/cppcodestylesettings.h b/src/plugins/cpptools/cppcodestylesettings.h
index c2cb18d910b..664ee29503b 100644
--- a/src/plugins/cpptools/cppcodestylesettings.h
+++ b/src/plugins/cpptools/cppcodestylesettings.h
@@ -32,6 +32,8 @@
 
 #include "cpptools_global.h"
 
+#include <cplusplus/Overview.h>
+
 #include <QMetaType>
 #include <QVariant>
 
@@ -61,6 +63,12 @@ public:
     bool indentBlocksRelativeToSwitchLabels;
     bool indentControlFlowRelativeToSwitchLabels;
 
+    // Formatting of pointer and reference declarations, see Overview::StarBindFlag.
+    bool bindStarToIdentifier;
+    bool bindStarToTypeName;
+    bool bindStarToLeftSpecifier;
+    bool bindStarToRightSpecifier;
+
     // false: if (a &&
     //            b)
     //            c;
@@ -87,6 +95,21 @@ public:
     bool equals(const CppCodeStyleSettings &rhs) const;
     bool operator==(const CppCodeStyleSettings &s) const { return equals(s); }
     bool operator!=(const CppCodeStyleSettings &s) const { return !equals(s); }
+
+    /*! Returns an Overview configured by the current project's code style.
+
+        If no current project is available or an error occurs when getting the
+        current project's code style, the current global code style settings
+        are applied.
+        */
+    static CPlusPlus::Overview currentProjectCodeStyleOverview();
+
+    /*! Returns an Overview configured by the current global code style.
+
+        If there occurred an error getting the current global code style, a
+        default constructed Overview is returned.
+        */
+    static CPlusPlus::Overview currentGlobalCodeStyleOverview();
 };
 
 } // namespace CppTools
diff --git a/src/plugins/cpptools/cppcodestylesettingspage.cpp b/src/plugins/cpptools/cppcodestylesettingspage.cpp
index 5272fdda94f..770b498530f 100644
--- a/src/plugins/cpptools/cppcodestylesettingspage.cpp
+++ b/src/plugins/cpptools/cppcodestylesettingspage.cpp
@@ -27,21 +27,27 @@
 **
 ****************************************************************************/
 
-#include "cppcodestylesettingspage.h"
 #include "cppcodestylepreferences.h"
-#include "ui_cppcodestylesettingspage.h"
+#include "cppcodestylesettingspage.h"
+#include "cpppointerdeclarationformatter.h"
+#include "cppqtstyleindenter.h"
 #include "cpptoolsconstants.h"
 #include "cpptoolssettings.h"
-#include "cppqtstyleindenter.h"
-#include <texteditor/snippets/isnippetprovider.h>
-#include <texteditor/fontsettings.h>
+#include "ui_cppcodestylesettingspage.h"
+
+#include <Overview.h>
+#include <pp.h>
+
+#include <coreplugin/icore.h>
+#include <cppeditor/cppeditorconstants.h>
+#include <extensionsystem/pluginmanager.h>
+#include <texteditor/codestyleeditor.h>
 #include <texteditor/displaysettings.h>
-#include <texteditor/texteditorsettings.h>
+#include <texteditor/fontsettings.h>
+#include <texteditor/snippets/isnippetprovider.h>
 #include <texteditor/tabsettings.h>
-#include <texteditor/codestyleeditor.h>
-#include <extensionsystem/pluginmanager.h>
-#include <cppeditor/cppeditorconstants.h>
-#include <coreplugin/icore.h>
+#include <texteditor/texteditorsettings.h>
+
 #include <QTextBlock>
 #include <QTextStream>
 
@@ -194,6 +200,19 @@ static const char *defaultCodeStyleSnippets[] = {
     "    myInstance.longMemberName += bar +\n"
     "                                 foo;\n"
     "}\n"
+    ,
+    "int *foo(const Bar &b1, Bar &&b2, int*, int *&rpi)\n"
+    "{\n"
+    "    int*pi = 0;\n"
+    "    int*const*const cpcpi = &pi;\n"
+    "    int*const*pcpi = &pi;\n"
+    "    int**const cppi = &pi;\n"
+    "\n"
+    "    void (*foo)(char *s) = 0;\n"
+    "    int (*bar)[] = 0;\n"
+    "\n"
+    "    return pi;\n"
+    "}\n"
 };
 
 using namespace TextEditor;
@@ -202,6 +221,44 @@ namespace CppTools {
 
 namespace Internal {
 
+static void applyRefactorings(QTextDocument *textDocument, TextEditor::BaseTextEditorWidget *editor,
+                              const CppCodeStyleSettings &settings)
+{
+    // Preprocess source
+    Environment env;
+    Preprocessor preprocess(0, &env);
+    const QByteArray preprocessedSource
+        = preprocess.run(QLatin1String("<no-file>"), textDocument->toPlainText());
+
+    Document::Ptr cppDocument = Document::create(QLatin1String("<no-file>"));
+    cppDocument->setUtf8Source(preprocessedSource);
+    cppDocument->parse(Document::ParseTranlationUnit);
+    cppDocument->check();
+
+    CppRefactoringFilePtr cppRefactoringFile = CppRefactoringChanges::file(editor, cppDocument);
+
+    // Run the formatter
+    Overview overview;
+    overview.showReturnTypes = true;
+    overview.starBindFlags = Overview::StarBindFlags(0);
+
+    if (settings.bindStarToIdentifier)
+        overview.starBindFlags |= Overview::BindToIdentifier;
+    if (settings.bindStarToTypeName)
+        overview.starBindFlags |= Overview::BindToTypeName;
+    if (settings.bindStarToLeftSpecifier)
+        overview.starBindFlags |= Overview::BindToLeftSpecifier;
+    if (settings.bindStarToRightSpecifier)
+        overview.starBindFlags |= Overview::BindToRightSpecifier;
+
+    PointerDeclarationFormatter formatter(cppRefactoringFile, overview);
+    Utils::ChangeSet change = formatter.format(cppDocument->translationUnit()->ast());
+
+    // Apply change
+    QTextCursor cursor(textDocument);
+    change.apply(&cursor);
+}
+
 // ------------------ CppCodeStyleSettingsWidget
 
 CppCodeStylePreferencesWidget::CppCodeStylePreferencesWidget(QWidget *parent)
@@ -215,7 +272,7 @@ CppCodeStylePreferencesWidget::CppCodeStylePreferencesWidget(QWidget *parent)
 
     m_previews << m_ui->previewTextEditGeneral << m_ui->previewTextEditContent
                << m_ui->previewTextEditBraces << m_ui->previewTextEditSwitch
-               << m_ui->previewTextEditPadding;
+               << m_ui->previewTextEditPadding << m_ui->previewTextEditPointerReferences;
     for (int i = 0; i < m_previews.size(); ++i)
         m_previews[i]->setPlainText(QLatin1String(defaultCodeStyleSnippets[i]));
 
@@ -260,6 +317,14 @@ CppCodeStylePreferencesWidget::CppCodeStylePreferencesWidget(QWidget *parent)
        this, SLOT(slotCodeStyleSettingsChanged()));
     connect(m_ui->alignAssignments, SIGNAL(toggled(bool)),
        this, SLOT(slotCodeStyleSettingsChanged()));
+    connect(m_ui->bindStarToIdentifier, SIGNAL(toggled(bool)),
+       this, SLOT(slotCodeStyleSettingsChanged()));
+    connect(m_ui->bindStarToTypeName, SIGNAL(toggled(bool)),
+       this, SLOT(slotCodeStyleSettingsChanged()));
+    connect(m_ui->bindStarToLeftSpecifier, SIGNAL(toggled(bool)),
+       this, SLOT(slotCodeStyleSettingsChanged()));
+    connect(m_ui->bindStarToRightSpecifier, SIGNAL(toggled(bool)),
+       this, SLOT(slotCodeStyleSettingsChanged()));
 
     m_ui->categoryTab->setCurrentIndex(0);
 
@@ -308,6 +373,10 @@ CppCodeStyleSettings CppCodeStylePreferencesWidget::cppCodeStyleSettings() const
     set.indentStatementsRelativeToSwitchLabels = m_ui->indentCaseStatements->isChecked();
     set.indentBlocksRelativeToSwitchLabels = m_ui->indentCaseBlocks->isChecked();
     set.indentControlFlowRelativeToSwitchLabels = m_ui->indentCaseBreak->isChecked();
+    set.bindStarToIdentifier = m_ui->bindStarToIdentifier->isChecked();
+    set.bindStarToTypeName = m_ui->bindStarToTypeName->isChecked();
+    set.bindStarToLeftSpecifier = m_ui->bindStarToLeftSpecifier->isChecked();
+    set.bindStarToRightSpecifier = m_ui->bindStarToRightSpecifier->isChecked();
     set.extraPaddingForConditionsIfConfusingAlign = m_ui->extraPaddingConditions->isChecked();
     set.alignAssignments = m_ui->alignAssignments->isChecked();
 
@@ -337,6 +406,10 @@ void CppCodeStylePreferencesWidget::setCodeStyleSettings(const CppCodeStyleSetti
     m_ui->indentCaseStatements->setChecked(s.indentStatementsRelativeToSwitchLabels);
     m_ui->indentCaseBlocks->setChecked(s.indentBlocksRelativeToSwitchLabels);
     m_ui->indentCaseBreak->setChecked(s.indentControlFlowRelativeToSwitchLabels);
+    m_ui->bindStarToIdentifier->setChecked(s.bindStarToIdentifier);
+    m_ui->bindStarToTypeName->setChecked(s.bindStarToTypeName);
+    m_ui->bindStarToLeftSpecifier->setChecked(s.bindStarToLeftSpecifier);
+    m_ui->bindStarToRightSpecifier->setChecked(s.bindStarToRightSpecifier);
     m_ui->extraPaddingConditions->setChecked(s.extraPaddingForConditionsIfConfusingAlign);
     m_ui->alignAssignments->setChecked(s.alignAssignments);
     m_blockUpdates = wasBlocked;
@@ -352,6 +425,7 @@ void CppCodeStylePreferencesWidget::slotCurrentPreferencesChanged(TextEditor::IC
     m_ui->bracesGroupBox->setEnabled(enable);
     m_ui->switchGroupBox->setEnabled(enable);
     m_ui->alignmentGroupBox->setEnabled(enable);
+    m_ui->pointerReferencesGroupBox->setEnabled(enable);
     if (preview)
         updatePreview();
 }
@@ -376,10 +450,15 @@ QString CppCodeStylePreferencesWidget::searchKeywords() const
        << sep << m_ui->indentCaseStatements->text()
        << sep << m_ui->indentCaseBlocks->text()
        << sep << m_ui->indentCaseBreak->text()
+       << sep << m_ui->bindStarToIdentifier->text()
+       << sep << m_ui->bindStarToTypeName->text()
+       << sep << m_ui->bindStarToLeftSpecifier->text()
+       << sep << m_ui->bindStarToRightSpecifier->text()
        << sep << m_ui->contentGroupBox->title()
        << sep << m_ui->bracesGroupBox->title()
        << sep << m_ui->switchGroupBox->title()
        << sep << m_ui->alignmentGroupBox->title()
+       << sep << m_ui->pointerReferencesGroupBox->title()
        << sep << m_ui->extraPaddingConditions->text()
        << sep << m_ui->alignAssignments->text()
           ;
@@ -440,6 +519,7 @@ void CppCodeStylePreferencesWidget::updatePreview()
 
             block = block.next();
         }
+        applyRefactorings(doc, preview, ccss);
         tc.endEditBlock();
     }
 }
diff --git a/src/plugins/cpptools/cppcodestylesettingspage.ui b/src/plugins/cpptools/cppcodestylesettingspage.ui
index 0ca280a2f43..fed6d45722d 100644
--- a/src/plugins/cpptools/cppcodestylesettingspage.ui
+++ b/src/plugins/cpptools/cppcodestylesettingspage.ui
@@ -17,7 +17,7 @@
    <item>
     <widget class="QTabWidget" name="categoryTab">
      <property name="currentIndex">
-      <number>0</number>
+      <number>5</number>
      </property>
      <widget class="QWidget" name="generalTab">
       <attribute name="title">
@@ -404,6 +404,86 @@ if they would align to the next line</string>
        </item>
       </layout>
      </widget>
+     <widget class="QWidget" name="typesTab">
+      <attribute name="title">
+       <string>Pointers and References</string>
+      </attribute>
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <widget class="QGroupBox" name="pointerReferencesGroupBox">
+         <property name="title">
+          <string>Bind '*' and '&amp;&amp;' in types/declarations to</string>
+         </property>
+         <property name="flat">
+          <bool>true</bool>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_6">
+          <item>
+           <widget class="QCheckBox" name="bindStarToIdentifier">
+            <property name="toolTip">
+             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;This does not apply to the star and reference symbol in pointer/reference to functions and arrays, e.g.:
+&lt;pre&gt;   int (&amp;rf)() = ...;
+   int (*pf)() = ...;
+
+   int (&amp;ra)[2] = ...;
+   int (*pa)[2] = ...;
+
+&lt;/pre&gt;&lt;/body&gt;&lt;/html&gt;</string>
+            </property>
+            <property name="text">
+             <string>Identifier</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QCheckBox" name="bindStarToTypeName">
+            <property name="text">
+             <string>Type name</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QCheckBox" name="bindStarToLeftSpecifier">
+            <property name="text">
+             <string>Left const/volatile</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QCheckBox" name="bindStarToRightSpecifier">
+            <property name="toolTip">
+             <string>This does not apply to references.</string>
+            </property>
+            <property name="text">
+             <string>Right const/volatile</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="verticalSpacer_6">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>40</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="TextEditor::SnippetEditorWidget" name="previewTextEditPointerReferences">
+         <property name="plainText">
+          <string/>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
     </widget>
    </item>
   </layout>
-- 
GitLab