diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index 03fe1d9096d1aa34f07f102148d8943e49217990..497a2cfae66f02f71cc03be2f6c8941f09ad5ca2 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -1198,7 +1198,11 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
         break;
 
     case block_open:
-        if (parentState.type != case_cont)
+        // case_cont already adds some indent, revert it for a block
+        if (parentState.type == case_cont && !m_indentSubstatementBraces)
+            *indentDepth = *savedIndentDepth = parentState.savedIndentDepth;
+
+        if (m_indentSubstatementStatements)
             *indentDepth += m_indentSize;
         break;
 
@@ -1302,6 +1306,8 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
     case T_LBRACE: {
         if (topState.type == case_cont) {
             *indentDepth = topState.savedIndentDepth;
+            if (m_indentSubstatementBraces)
+                *indentDepth += m_indentSize;
             *paddingDepth = 0;
         // function definition - argument list is expression state
         } else if (topState.type == expression && previousState.type == declaration_start) {
@@ -1332,8 +1338,8 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
     }
     case T_RBRACE: {
         if (topState.type == block_open && previousState.type == case_cont) {
-            *indentDepth = previousState.savedIndentDepth;
-            *paddingDepth = previousState.savedPaddingDepth;
+            *indentDepth = topState.savedIndentDepth;
+            *paddingDepth = topState.savedPaddingDepth;
             break;
         }
         for (int i = 0; state(i).type != topmost_intro; ++i) {
@@ -1365,10 +1371,16 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
     //    }
     //    break;
     case T_DEFAULT:
-    case T_CASE:
+    case T_CASE: {
+        int lastSubstatementIndent = 0;
         for (int i = 0; state(i).type != topmost_intro; ++i) {
             const int type = state(i).type;
-            if (type == switch_statement || type == case_cont) {
+            if (type == substatement_open) {
+                lastSubstatementIndent = state(i).savedIndentDepth;
+            } else if (type == switch_statement) {
+                *indentDepth = lastSubstatementIndent;
+                break;
+            } else if (type == case_cont) {
                 *indentDepth = state(i).savedIndentDepth;
                 break;
             } else if (type == topmost_intro) {
@@ -1376,6 +1388,7 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
             }
         }
         break;
+    }
     case T_PUBLIC:
     case T_PRIVATE:
     case T_PROTECTED:
diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
index df9954ae1528db5b8ae2f7c090dceb96f38f7eda..3eb1f2a748066122af77a69f849aaf6fb5d59f2e 100644
--- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
+++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
@@ -54,6 +54,8 @@ private Q_SLOTS:
     void macrosNoSemicolon2();
     void renamedNamespace();
     void cpp0xFor();
+    void gnuStyleSwitch();
+    void whitesmithsStyleSwitch();
 };
 
 struct Line {
@@ -820,6 +822,9 @@ void tst_CodeFormatter::gnuStyle()
          << Line("        if (b) {")
          << Line("            fpp;")
          << Line("        }")
+         << Line("        {")
+         << Line("            foo;")
+         << Line("        }")
          << Line("    }")
          << Line("};")
          ;
@@ -840,6 +845,9 @@ void tst_CodeFormatter::whitesmithsStyle()
          << Line("        if (b) {")
          << Line("            fpp;")
          << Line("            }")
+         << Line("        {")
+         << Line("        foo;")
+         << Line("        }")
          << Line("        }")
          << Line("    };")
          ;
@@ -1034,6 +1042,62 @@ void tst_CodeFormatter::cpp0xFor()
     checkIndent(data);
 }
 
+void tst_CodeFormatter::gnuStyleSwitch()
+{
+    QList<Line> data;
+    data << Line("void foo()")
+         << Line("{")
+         << Line("    switch (a)")
+         << Line("        {")
+         << Line("        case 1:")
+         << Line("            foo;")
+         << Line("            break;")
+         << Line("        case 2: {")
+         << Line("                bar;")
+         << Line("                continue;")
+         << Line("            }")
+         << Line("        case 3:")
+         << Line("            {")
+         << Line("                bar;")
+         << Line("                continue;")
+         << Line("            }")
+         << Line("        case 4:")
+         << Line("        case 5:")
+         << Line("            ;")
+         << Line("        }")
+         << Line("}")
+         ;
+    checkIndent(data, 1);
+}
+
+void tst_CodeFormatter::whitesmithsStyleSwitch()
+{
+    QList<Line> data;
+    data << Line("void foo()")
+         << Line("    {")
+         << Line("    switch (a)")
+         << Line("        {")
+         << Line("        case 1:")
+         << Line("            foo;")
+         << Line("            break;")
+         << Line("        case 2: {")
+         << Line("            bar;")
+         << Line("            continue;")
+         << Line("            }")
+         << Line("        case 3:")
+         << Line("            {")
+         << Line("            bar;")
+         << Line("            continue;")
+         << Line("            }")
+         << Line("        case 4:")
+         << Line("        case 5:")
+         << Line("            ;")
+         << Line("        }")
+         << Line("    }")
+         ;
+    checkIndent(data, 2);
+}
+
 QTEST_APPLESS_MAIN(tst_CodeFormatter)
 #include "tst_codeformatter.moc"