Merge branch 'master' into codeStyleExtractor
authorjamesbrain <marso.des@gmail.com>
Thu, 1 Oct 2015 10:48:14 +0000 (13:48 +0300)
committerjamesbrain <marso.des@gmail.com>
Thu, 1 Oct 2015 10:48:14 +0000 (13:48 +0300)
27 files changed:
java/java-impl/src/com/intellij/psi/codeStyle/extractor/differ/FJavaExtractor.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleIntegerSettingRepresentation.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSelectSettingRepresentation.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingRepresentation.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/FUtils.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FDiffer.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FDifferBase.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FLangCodeStyleExtractor.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FBruteForceProcessor.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FCodeStyleDeriveProcessor.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FGenProcessor.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FClassSerializer.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FGeneration.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FGens.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValue.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValuesExtractionResult.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValuesExtractionResultImpl.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleBlankLinesPanel.java
platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSpacesPanel.java
platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java
platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java
platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/FExtractCodeStyleAction.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/ui/FCodeStyleSettingsNameProvider.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/ui/FExtractedSettingsDialog.java [new file with mode: 0644]
platform/platform-resources/src/META-INF/LangExtensionPoints.xml
platform/platform-resources/src/idea/LangActions.xml
resources/src/META-INF/IdeaPlugin.xml

diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/extractor/differ/FJavaExtractor.java b/java/java-impl/src/com/intellij/psi/codeStyle/extractor/differ/FJavaExtractor.java
new file mode 100644 (file)
index 0000000..171920d
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.differ;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaCodeFragment;
+import com.intellij.psi.JavaCodeFragmentFactory;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.impl.source.SourceTreeToPsiMap;
+import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * @author Roman.Shein
+ * @since 05.08.2015.
+ * TODO: move from debugger-impl to more meaningful location?
+ */
+public class FJavaExtractor implements FLangCodeStyleExtractor {
+    @NotNull
+    @Override
+    public FDiffer getDiffer(final Project project, PsiFile psiFile, CodeStyleSettings settings) {
+        return new FDifferBase(project, psiFile, settings) {
+            @Override
+            public String reformattedText() {
+                final JavaCodeFragment file = JavaCodeFragmentFactory.getInstance(project).
+                    createCodeBlockCodeFragment(myOrigText, myFile, false);
+
+                WriteCommandAction.runWriteCommandAction(myProject, "CodeStyleSettings extractor", "CodeStyleSettings extractor", new Runnable() {
+                    @Override
+                    public void run() {
+                        final ASTNode treeElement = SourceTreeToPsiMap.psiElementToTree(file);
+                        assert (treeElement != null);
+
+                        SourceTreeToPsiMap.treeElementToPsi(new CodeFormatterFacade(mySettings, file.getLanguage()).processElement(treeElement));
+                    }
+                }, file);
+                return file.getText();
+            }
+        };
+    }
+
+    @NotNull
+    @Override
+    public Collection<FValue.VAR_KIND> getCustomVarKinds() {
+        return new LinkedList<FValue.VAR_KIND>();
+    }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleIntegerSettingRepresentation.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleIntegerSettingRepresentation.java
new file mode 100644 (file)
index 0000000..46f1e57
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Roman.Shein
+ * @since 15.09.2015.
+ */
+public class CodeStyleIntegerSettingRepresentation extends CodeStyleSettingRepresentation {
+
+  protected int myLowerBound;
+  protected int myUpperBound;
+  protected int myDefaultValue;
+  protected String myDefaultValueUiName;
+
+  public CodeStyleIntegerSettingRepresentation(@NotNull String fieldName, @NotNull String uiName, int lowerBound, int upperBound, int defaultValue, String defaultValueUiName) {
+    super(fieldName, uiName);
+    myLowerBound = lowerBound;
+    myUpperBound = upperBound;
+    myDefaultValue = defaultValue;
+    myDefaultValueUiName = defaultValueUiName;
+  }
+
+  public int getLowerBound() {
+    return myLowerBound;
+  }
+
+  public int getUpperBound() {
+    return myUpperBound;
+  }
+
+  public int getDefaultValue() {
+    return myDefaultValue;
+  }
+
+  @Override
+  @NotNull
+  public String getValueUiName(@NotNull Object value) {
+    if (value instanceof Integer) {
+      int intValue = (Integer) value;
+      return intValue == myDefaultValue ? myDefaultValueUiName : super.getValueUiName(value);
+    } else {
+      return super.getValueUiName(value);
+    }
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSelectSettingRepresentation.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSelectSettingRepresentation.java
new file mode 100644 (file)
index 0000000..14ddbb9
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Roman.Shein
+ * @since 16.09.2015.
+ */
+public class CodeStyleSelectSettingRepresentation extends CodeStyleSettingRepresentation {
+
+  @NotNull
+  protected int[] myValues;
+  @NotNull
+  protected String[] myValueUiNames;
+
+  protected int myLowerBound;
+  protected int myUpperBound;
+
+  public CodeStyleSelectSettingRepresentation(@NotNull String fieldName, @NotNull String uiName,
+                                               @NotNull int[] values, @NotNull String[] valueUiNames) {
+    super(fieldName, uiName);
+
+    assert(values.length == valueUiNames.length);
+    assert(values.length > 0);
+
+    myValues = values;
+    myValueUiNames = valueUiNames;
+
+    //TODO get bounds more gracefully
+    myLowerBound = values[0];
+    myUpperBound = values[0];
+    for (int value : values) {
+      myLowerBound = Math.min(value, myLowerBound);
+      myUpperBound = Math.max(value, myUpperBound);
+    }
+  }
+
+  @Override
+  @NotNull
+  public String getValueUiName(@NotNull Object value) {
+    if (value instanceof Integer) {
+      int intValue = (Integer) value;
+      for (int i = 0; i < myValues.length; ++i) {
+        if (myValues[i] == intValue) return myValueUiNames[i];
+      }
+      return super.getValueUiName(value);
+    } else {
+      return super.getValueUiName(value);
+    }
+  }
+
+  public int getLowerBound() {
+    return myLowerBound;
+  }
+
+  public int getUpperBound() {
+    return myUpperBound;
+  }
+
+  @NotNull
+  public int[] getValues() {
+    return myValues;
+  }
+
+  @NotNull
+  public String[] getOptions() {
+    return myValueUiNames;
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingRepresentation.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingRepresentation.java
new file mode 100644 (file)
index 0000000..2b9aa25
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle;
+
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import static com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Roman.Shein
+ * @since 15.09.2015.
+ */
+public class CodeStyleSettingRepresentation {
+
+  public static class SettingsGroup {
+    @Nullable
+    public final String name;
+
+    public SettingsGroup(@Nullable String name) {
+      this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (o instanceof SettingsGroup) {
+        SettingsGroup other = (SettingsGroup) o;
+        return name != null && name.equals(other.name);
+      } else {
+        return false;
+      }
+    }
+
+    @Override
+    public int hashCode() {
+      return name == null ? 0 : name.hashCode();
+    }
+
+    public boolean isNull() {
+      return name == null;
+    }
+  }
+
+  @NotNull
+  protected String myFieldName;
+
+  @NotNull
+  protected String myUiName;
+
+  public CodeStyleSettingRepresentation(@NotNull String fieldName, @NotNull String uiName) {
+    myFieldName = fieldName;
+    myUiName = uiName;
+  }
+
+  @NotNull
+  public String getFieldName() {
+    return myFieldName;
+  }
+
+  @NotNull
+  public String getUiName() {
+    return myUiName;
+  }
+
+  public void setUiName(@NotNull String newName) {
+    myUiName = newName;
+  }
+
+  @NotNull
+  public String getValueUiName(@NotNull Object value) {
+    return value.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return (o instanceof CodeStyleSettingRepresentation) && ((CodeStyleSettingRepresentation)o).getFieldName().equals(getFieldName());
+  }
+
+  @Override
+  public int hashCode() {
+    return myFieldName.hashCode();
+  }
+
+  protected static void putGroupTop(@NotNull Map<SettingsGroup, List<CodeStyleSettingRepresentation>> result, @NotNull String fieldName,
+                                    @NotNull String uiName, int[] values, String[] valueUiNames) {
+    result.put(new SettingsGroup(null), ContainerUtil.<CodeStyleSettingRepresentation>newLinkedList(
+      new CodeStyleSelectSettingRepresentation(fieldName, uiName, values, valueUiNames)
+    ));
+  }
+
+  @NotNull
+  public static Map<SettingsGroup, List<CodeStyleSettingRepresentation>> getStandardSettings(LanguageCodeStyleSettingsProvider.SettingsType settingsType) {
+    Map<SettingsGroup, List<CodeStyleSettingRepresentation>> result = ContainerUtil.newLinkedHashMap();
+    switch (settingsType) {
+      case BLANK_LINES_SETTINGS:
+        result.put(new SettingsGroup(BLANK_LINES_KEEP), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("KEEP_BLANK_LINES_IN_DECLARATIONS",
+                                             ApplicationBundle.message("editbox.keep.blanklines.in.declarations")),
+          new CodeStyleSettingRepresentation("KEEP_BLANK_LINES_IN_CODE", ApplicationBundle.message("editbox.keep.blanklines.in.code")),
+          new CodeStyleSettingRepresentation("KEEP_BLANK_LINES_BEFORE_RBRACE",
+                                             ApplicationBundle.message("editbox.keep.blanklines.before.rbrace"))
+        ));
+        
+        result.put(new SettingsGroup(BLANK_LINES), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("BLANK_LINES_BEFORE_PACKAGE",
+                                             ApplicationBundle.message("editbox.blanklines.before.package.statement")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_AFTER_PACKAGE",
+                                             ApplicationBundle.message("editbox.blanklines.after.package.statement")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_BEFORE_IMPORTS", ApplicationBundle.message("editbox.blanklines.before.imports")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_AFTER_IMPORTS", ApplicationBundle.message("editbox.blanklines.after.imports")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_AROUND_CLASS", ApplicationBundle.message("editbox.blanklines.around.class")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_AFTER_CLASS_HEADER",
+                                             ApplicationBundle.message("editbox.blanklines.after.class.header")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_AFTER_ANONYMOUS_CLASS_HEADER",
+                                             ApplicationBundle.message("editbox.blanklines.after.anonymous.class.header")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_AROUND_FIELD_IN_INTERFACE", "Around field in interface:"),
+          //TODO why is thi not loaded from bundle??
+          new CodeStyleSettingRepresentation("BLANK_LINES_AROUND_FIELD", ApplicationBundle.message("editbox.blanklines.around.field")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_AROUND_METHOD_IN_INTERFACE", "Around method in interface:"),
+          //TODO why is thi not loaded from bundle??
+          new CodeStyleSettingRepresentation("BLANK_LINES_AROUND_METHOD", ApplicationBundle.message("editbox.blanklines.around.method")),
+          new CodeStyleSettingRepresentation("BLANK_LINES_BEFORE_METHOD_BODY",
+                                             ApplicationBundle.message("editbox.blanklines.before.method.body"))
+        ));
+        break;
+      case SPACING_SETTINGS:
+        result.put(new SettingsGroup(SPACES_BEFORE_PARENTHESES), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_METHOD_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.method.declaration.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_METHOD_CALL_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.method.call.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_WHILE_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.while.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_SWITCH_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.switch.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_CATCH_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.catch.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_SYNCHRONIZED_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.synchronized.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_ANOTATION_PARAMETER_LIST",
+                                             ApplicationBundle.message("checkbox.spaces.annotation.parameters"))
+        ));
+
+        result.put(new SettingsGroup(SPACES_AROUND_OPERATORS), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_AROUND_ASSIGNMENT_OPERATORS",
+                                             ApplicationBundle.message("checkbox.spaces.assignment.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_LOGICAL_OPERATORS",
+                                             ApplicationBundle.message("checkbox.spaces.logical.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_EQUALITY_OPERATORS",
+                                             ApplicationBundle.message("checkbox.spaces.equality.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_RELATIONAL_OPERATORS",
+                                             ApplicationBundle.message("checkbox.spaces.relational.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_BITWISE_OPERATORS",
+                                             ApplicationBundle.message("checkbox.spaces.bitwise.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_ADDITIVE_OPERATORS",
+                                             ApplicationBundle.message("checkbox.spaces.additive.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_MULTIPLICATIVE_OPERATORS",
+                                             ApplicationBundle.message("checkbox.spaces.multiplicative.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_SHIFT_OPERATORS", ApplicationBundle.message("checkbox.spaces.shift.operators")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_UNARY_OPERATOR",
+                                             ApplicationBundle.message("checkbox.spaces.around.unary.operator")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_LAMBDA_ARROW", ApplicationBundle.message("checkbox.spaces.around.lambda.arrow")),
+          new CodeStyleSettingRepresentation("SPACE_AROUND_METHOD_REF_DBL_COLON",
+                                             ApplicationBundle.message("checkbox.spaces.around.method.ref.dbl.colon.arrow"))
+        ));
+
+        result.put(new SettingsGroup(SPACES_BEFORE_LEFT_BRACE), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_CLASS_LBRACE", ApplicationBundle.message("checkbox.spaces.class.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_METHOD_LBRACE", ApplicationBundle.message("checkbox.spaces.method.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_IF_LBRACE", ApplicationBundle.message("checkbox.spaces.if.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_ELSE_LBRACE", ApplicationBundle.message("checkbox.spaces.else.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_FOR_LBRACE", ApplicationBundle.message("checkbox.spaces.for.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_WHILE_LBRACE", ApplicationBundle.message("checkbox.spaces.while.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_DO_LBRACE", ApplicationBundle.message("checkbox.spaces.do.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_SWITCH_LBRACE", ApplicationBundle.message("checkbox.spaces.switch.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_TRY_LBRACE", ApplicationBundle.message("checkbox.spaces.try.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_CATCH_LBRACE", ApplicationBundle.message("checkbox.spaces.catch.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_FINALLY_LBRACE",
+                                             ApplicationBundle.message("checkbox.spaces.finally.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_SYNCHRONIZED_LBRACE",
+                                             ApplicationBundle.message("checkbox.spaces.synchronized.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE",
+                                             ApplicationBundle.message("checkbox.spaces.array.initializer.left.brace")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE",
+                                             ApplicationBundle.message("checkbox.spaces.annotation.array.initializer.left.brace"))
+        ));
+
+        result.put(new SettingsGroup(SPACES_BEFORE_KEYWORD), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_ELSE_KEYWORD", ApplicationBundle.message("checkbox.spaces.else.keyword")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_WHILE_KEYWORD", ApplicationBundle.message("checkbox.spaces.while.keyword")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_CATCH_KEYWORD", ApplicationBundle.message("checkbox.spaces.catch.keyword")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_FINALLY_KEYWORD", ApplicationBundle.message("checkbox.spaces.finally.keyword"))
+        ));
+
+        result.put(new SettingsGroup(SPACES_WITHIN), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_BRACES", ApplicationBundle.message("checkbox.spaces.within.braces")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_BRACKETS", ApplicationBundle.message("checkbox.spaces.within.brackets")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_ARRAY_INITIALIZER_BRACES",
+                                             ApplicationBundle.message("checkbox.spaces.within.array.initializer.braces")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_EMPTY_ARRAY_INITIALIZER_BRACES",
+                                             ApplicationBundle.message("checkbox.spaces.within.empty.array.initializer.braces")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_PARENTHESES", ApplicationBundle.message("checkbox.spaces.within.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_METHOD_CALL_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.call.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.checkbox.spaces.empty.method.call.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_METHOD_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.declaration.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_EMPTY_METHOD_PARENTHESES", ApplicationBundle
+            .message("checkbox.spaces.checkbox.spaces.empty.method.declaration.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_WHILE_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.while.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_SWITCH_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.switch.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_CATCH_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.catch.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_SYNCHRONIZED_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.synchronized.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_CAST_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.type.cast.parentheses")),
+          new CodeStyleSettingRepresentation("SPACE_WITHIN_ANNOTATION_PARENTHESES",
+                                             ApplicationBundle.message("checkbox.spaces.annotation.parentheses"))
+        ));
+
+        result.put(new SettingsGroup(SPACES_IN_TERNARY_OPERATOR), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_QUEST", ApplicationBundle.message("checkbox.spaces.before.question")),
+          new CodeStyleSettingRepresentation("SPACE_AFTER_QUEST", ApplicationBundle.message("checkbox.spaces.after.question")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_COLON", ApplicationBundle.message("checkbox.spaces.before.colon")),
+          new CodeStyleSettingRepresentation("SPACE_AFTER_COLON", ApplicationBundle.message("checkbox.spaces.after.colon"))
+        ));
+
+        result.put(new SettingsGroup(SPACES_WITHIN_TYPE_ARGUMENTS), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS",
+                                             ApplicationBundle.message("checkbox.spaces.after.comma"))
+        ));
+
+        result.put(new SettingsGroup(SPACES_IN_TYPE_ARGUMENTS), ContainerUtil.<CodeStyleSettingRepresentation>newLinkedList());
+
+        result.put(new SettingsGroup(SPACES_IN_TYPE_PARAMETERS), ContainerUtil.<CodeStyleSettingRepresentation>newLinkedList());
+        
+        result.put(new SettingsGroup(SPACES_OTHER), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_COMMA", ApplicationBundle.message("checkbox.spaces.before.comma")),
+          new CodeStyleSettingRepresentation("SPACE_AFTER_COMMA", ApplicationBundle.message("checkbox.spaces.after.comma")),
+          new CodeStyleSettingRepresentation("SPACE_BEFORE_SEMICOLON", ApplicationBundle.message("checkbox.spaces.before.semicolon")),
+          new CodeStyleSettingRepresentation("SPACE_AFTER_SEMICOLON", ApplicationBundle.message("checkbox.spaces.after.semicolon")),
+          new CodeStyleSettingRepresentation("SPACE_AFTER_TYPE_CAST", ApplicationBundle.message("checkbox.spaces.after.type.cast"))
+        ));
+        break;
+      case WRAPPING_AND_BRACES_SETTINGS:
+        result.put(new SettingsGroup(null), ContainerUtil.<CodeStyleSettingRepresentation>newLinkedList(
+          new CodeStyleIntegerSettingRepresentation("RIGHT_MARGIN", ApplicationBundle.message("editbox.right.margin.columns"), 0, 999, -1,
+                                                    ApplicationBundle.message("settings.code.style.default.general"))
+        ));
+
+        putGroupTop(result, "WRAP_ON_TYPING", ApplicationBundle.message("wrapping.wrap.on.typing"), WRAP_ON_TYPING_VALUES,
+                    WRAP_ON_TYPING_OPTIONS);
+
+        result.put(new SettingsGroup(WRAPPING_KEEP), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("KEEP_LINE_BREAKS", ApplicationBundle.message("wrapping.keep.line.breaks")),
+          new CodeStyleSettingRepresentation("KEEP_FIRST_COLUMN_COMMENT",
+                                             ApplicationBundle.message("wrapping.keep.comment.at.first.column")),
+          new CodeStyleSettingRepresentation("KEEP_CONTROL_STATEMENT_IN_ONE_LINE",
+                                             ApplicationBundle.message("checkbox.keep.when.reformatting.control.statement.in.one.line")),
+          new CodeStyleSettingRepresentation("KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE",
+                                             ApplicationBundle.message("wrapping.keep.multiple.expressions.in.one.line")),
+          new CodeStyleSettingRepresentation("KEEP_SIMPLE_BLOCKS_IN_ONE_LINE",
+                                             ApplicationBundle.message("wrapping.keep.simple.blocks.in.one.line")),
+          new CodeStyleSettingRepresentation("KEEP_SIMPLE_METHODS_IN_ONE_LINE",
+                                             ApplicationBundle.message("wrapping.keep.simple.methods.in.one.line")),
+          new CodeStyleSettingRepresentation("KEEP_SIMPLE_CLASSES_IN_ONE_LINE",
+                                             ApplicationBundle.message("wrapping.keep.simple.classes.in.one.line"))
+        ));
+
+        result.put(new SettingsGroup(null), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("WRAP_LONG_LINES", ApplicationBundle.message("wrapping.long.lines"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_COMMENTS), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("WRAP_COMMENTS", ApplicationBundle.message("wrapping.comments.wrap.at.right.margin"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_BRACES), ContainerUtil.<CodeStyleSettingRepresentation>newLinkedList(
+          new CodeStyleSelectSettingRepresentation("CLASS_BRACE_STYLE",
+                                                   ApplicationBundle.message("wrapping.brace.placement.class.declaration"),
+                                                   BRACE_PLACEMENT_VALUES, BRACE_PLACEMENT_OPTIONS),
+          new CodeStyleSelectSettingRepresentation("METHOD_BRACE_STYLE",
+                                                   ApplicationBundle.message("wrapping.brace.placement.method.declaration"),
+                                                   BRACE_PLACEMENT_VALUES, BRACE_PLACEMENT_OPTIONS),
+          new CodeStyleSelectSettingRepresentation("BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.other"),
+                                                   BRACE_PLACEMENT_VALUES, BRACE_PLACEMENT_OPTIONS)
+
+        ));
+
+        putGroupTop(result, "EXTENDS_LIST_WRAP", WRAPPING_EXTENDS_LIST, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_EXTENDS_LIST), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_EXTENDS_LIST", ApplicationBundle.message("wrapping.align.when.multiline"))
+        ));
+
+        putGroupTop(result, "EXTENDS_KEYWORD_WRAP", WRAPPING_EXTENDS_KEYWORD, WRAP_VALUES_FOR_SINGLETON, WRAP_OPTIONS_FOR_SINGLETON);
+
+        putGroupTop(result, "THROWS_LIST_WRAP", WRAPPING_THROWS_LIST, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_THROWS_LIST), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_THROWS_LIST", ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("ALIGN_THROWS_KEYWORD", ApplicationBundle.message("wrapping.align.throws.keyword"))
+        ));
+
+        putGroupTop(result, "THROWS_KEYWORD_WRAP", WRAPPING_THROWS_KEYWORD, WRAP_VALUES_FOR_SINGLETON, WRAP_OPTIONS_FOR_SINGLETON);
+
+        putGroupTop(result, "METHOD_PARAMETERS_WRAP", WRAPPING_METHOD_PARAMETERS, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_METHOD_PARAMETERS), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_PARAMETERS", ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.new.line.after.lpar")),
+          new CodeStyleSettingRepresentation("METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.rpar.on.new.line"))
+        ));
+
+        putGroupTop(result, "CALL_PARAMETERS_WRAP", WRAPPING_METHOD_ARGUMENTS_WRAPPING, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_METHOD_ARGUMENTS_WRAPPING), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_PARAMETERS_IN_CALLS",
+                                             ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("PREFER_PARAMETERS_WRAP",
+                                             ApplicationBundle.message("wrapping.take.priority.over.call.chain.wrapping")),
+          new CodeStyleSettingRepresentation("CALL_PARAMETERS_LPAREN_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.new.line.after.lpar")),
+          new CodeStyleSettingRepresentation("CALL_PARAMETERS_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_METHOD_PARENTHESES), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_METHOD_BRACKETS", ApplicationBundle.message("wrapping.align.when.multiline"))
+        ));
+
+        putGroupTop(result, "METHOD_CALL_CHAIN_WRAP", WRAPPING_CALL_CHAIN, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_CALL_CHAIN), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("WRAP_FIRST_METHOD_IN_CALL_CHAIN",
+                                             ApplicationBundle.message("wrapping.chained.method.call.first.on.new.line")),
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_CHAINED_METHODS", ApplicationBundle.message("wrapping.align.when.multiline"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_IF_STATEMENT), ContainerUtil.newLinkedList(
+          new CodeStyleSelectSettingRepresentation("IF_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
+                                                   BRACE_OPTIONS),
+          new CodeStyleSettingRepresentation("ELSE_ON_NEW_LINE", ApplicationBundle.message("wrapping.else.on.new.line")),
+          new CodeStyleSettingRepresentation("SPECIAL_ELSE_IF_TREATMENT",
+                                             ApplicationBundle.message("wrapping.special.else.if.braces.treatment"))
+        ));
+
+        putGroupTop(result, "FOR_STATEMENT_WRAP", WRAPPING_FOR_STATEMENT, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_FOR_STATEMENT), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_FOR", ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("FOR_STATEMENT_LPAREN_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.new.line.after.lpar")),
+          new CodeStyleSettingRepresentation("FOR_STATEMENT_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line")),
+          new CodeStyleSelectSettingRepresentation("FOR_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
+                                                   BRACE_OPTIONS)
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_WHILE_STATEMENT), ContainerUtil.<CodeStyleSettingRepresentation>newLinkedList(
+          new CodeStyleSelectSettingRepresentation("WHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
+                                                   BRACE_OPTIONS)
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_DOWHILE_STATEMENT), ContainerUtil.newLinkedList(
+          new CodeStyleSelectSettingRepresentation("DOWHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
+                                                   BRACE_OPTIONS),
+          new CodeStyleSettingRepresentation("WHILE_ON_NEW_LINE", ApplicationBundle.message("wrapping.while.on.new.line"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_SWITCH_STATEMENT), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("INDENT_CASE_FROM_SWITCH", ApplicationBundle.message("wrapping.indent.case.from.switch")),
+          new CodeStyleSettingRepresentation("INDENT_BREAK_FROM_CASE", ApplicationBundle.message("wrapping.indent.break.from.case"))
+        ));
+
+        putGroupTop(result, "RESOURCE_LIST_WRAP", WRAPPING_TRY_RESOURCE_LIST, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_TRY_RESOURCE_LIST), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_RESOURCES", ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("RESOURCE_LIST_LPAREN_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.new.line.after.lpar")),
+          new CodeStyleSettingRepresentation("RESOURCE_LIST_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_TRY_STATEMENT), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("CATCH_ON_NEW_LINE", ApplicationBundle.message("wrapping.catch.on.new.line")),
+          new CodeStyleSettingRepresentation("FINALLY_ON_NEW_LINE", ApplicationBundle.message("wrapping.finally.on.new.line"))
+        ));
+
+        putGroupTop(result, "BINARY_OPERATION_WRAP", WRAPPING_BINARY_OPERATION, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_BINARY_OPERATION), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_BINARY_OPERATION",
+                                             ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("BINARY_OPERATION_SIGN_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.operation.sign.on.next.line")),
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION",
+                                             ApplicationBundle.message("wrapping.align.parenthesised.when.multiline")),
+          new CodeStyleSettingRepresentation("PARENTHESES_EXPRESSION_LPAREN_WRAP",
+                                             ApplicationBundle.message("wrapping.new.line.after.lpar")),
+          new CodeStyleSettingRepresentation("PARENTHESES_EXPRESSION_RPAREN_WRAP", ApplicationBundle.message("wrapping.rpar.on.new.line"))
+        ));
+
+        putGroupTop(result, "ASSIGNMENT_WRAP", WRAPPING_ASSIGNMENT, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_ASSIGNMENT), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_ASSIGNMENT", ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.assignment.sign.on.next.line"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_FIELDS_VARIABLES_GROUPS), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_GROUP_FIELD_DECLARATIONS",
+                                             ApplicationBundle.message("wrapping.align.fields.in.columns")),
+          new CodeStyleSettingRepresentation("ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS",
+                                             ApplicationBundle.message("wrapping.align.variables.in.columns"))
+        ));
+
+        putGroupTop(result, "TERNARY_OPERATION_WRAP", WRAPPING_TERNARY_OPERATION, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_TERNARY_OPERATION), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_TERNARY_OPERATION",
+                                             ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("TERNARY_OPERATION_SIGNS_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.quest.and.colon.signs.on.next.line"))
+        ));
+
+        putGroupTop(result, "ARRAY_INITIALIZER_WRAP", WRAPPING_ARRAY_INITIALIZER, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_ARRAY_INITIALIZER), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION",
+                                             ApplicationBundle.message("wrapping.align.when.multiline")),
+          new CodeStyleSettingRepresentation("ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.new.line.after.lbrace")),
+          new CodeStyleSettingRepresentation("ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.rbrace.on.new.line"))
+        ));
+
+        result.put(new SettingsGroup(WRAPPING_MODIFIER_LIST), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("MODIFIER_LIST_WRAP", ApplicationBundle.message("wrapping.after.modifier.list"))
+        ));
+
+        putGroupTop(result, "ASSERT_STATEMENT_WRAP", WRAPPING_ASSERT_STATEMENT, WRAP_VALUES, WRAP_OPTIONS);
+        result.put(new SettingsGroup(WRAPPING_ASSERT_STATEMENT), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("ASSERT_STATEMENT_COLON_ON_NEXT_LINE",
+                                             ApplicationBundle.message("wrapping.colon.signs.on.next.line"))
+        ));
+
+        putGroupTop(result, "ENUM_CONSTANTS_WRAP", ApplicationBundle.message("wrapping.enum.constants"), WRAP_VALUES, WRAP_OPTIONS);
+        putGroupTop(result, "CLASS_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.classes.annotation"), WRAP_VALUES, WRAP_OPTIONS);
+        putGroupTop(result, "METHOD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.methods.annotation"), WRAP_VALUES, WRAP_OPTIONS);
+        putGroupTop(result, "FIELD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.fields.annotation"), WRAP_VALUES, WRAP_OPTIONS);
+        putGroupTop(result, "PARAMETER_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.parameters.annotation"), WRAP_VALUES, WRAP_OPTIONS);
+        putGroupTop(result, "VARIABLE_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.local.variables.annotation"), WRAP_VALUES,
+                    WRAP_OPTIONS);
+        break;
+      case INDENT_SETTINGS:
+        result.put(new SettingsGroup(null), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("INDENT_SIZE", ApplicationBundle.message("editbox.indent.indent"))
+        ));
+        result.put(new SettingsGroup(null), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("CONTINUATION_INDENT_SIZE", ApplicationBundle.message("editbox.indent.continuation.indent"))
+        ));
+        result.put(new SettingsGroup(null), ContainerUtil.newLinkedList(
+          new CodeStyleSettingRepresentation("TAB_SIZE", ApplicationBundle.message("editbox.indent.tab.size"))
+        ));
+        break;
+      case LANGUAGE_SPECIFIC:
+    }
+    return result;
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/FUtils.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/FUtils.java
new file mode 100644 (file)
index 0000000..0703132
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsProvider;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
+import com.intellij.psi.codeStyle.extractor.differ.FDiffer;
+import com.intellij.psi.codeStyle.extractor.values.FGeneration;
+import com.intellij.psi.codeStyle.extractor.values.FGens;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import com.intellij.psi.codeStyle.extractor.values.FValuesExtractionResult;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class FUtils {
+  public static int CRITICAL_SYMBOL_WEIGHT = 100;
+
+  public static void logError(String message) {
+    System.out.println(message); //TODO reasonable implementation
+  }
+
+  public static int getTabSize(@Nullable CommonCodeStyleSettings.IndentOptions options) {
+    return options == null ? 4 : options.TAB_SIZE;
+  }
+
+  public static int getNormalizedLength(@Nullable CommonCodeStyleSettings.IndentOptions options, @NotNull String text) {
+    return text
+      .replaceAll(
+        "\t",
+        StringUtil.repeatSymbol(' ', getTabSize(options)))
+      .replaceAll(
+        "\n",
+        StringUtil.repeatSymbol(' ', CRITICAL_SYMBOL_WEIGHT))
+      .length();
+  }
+
+  public static boolean isSpace(char c) {
+    return " \t\n".indexOf(c) >= 0;
+  }
+
+  public static boolean isBracket(char c) {
+    return "(){}[]<>".indexOf(c) >= 0;
+  }
+
+  public static int getDiff(@Nullable CommonCodeStyleSettings.IndentOptions options, @NotNull String oldV, @NotNull String newV) {
+    oldV = oldV.trim();
+    newV = newV.trim();
+    int diff = 0;
+    int oPos = 0, nPos = 0;
+    int oEnd = oldV.length(), nEnd = newV.length();
+
+    StringBuilder oSp = new StringBuilder();
+    StringBuilder nSp = new StringBuilder();
+    char ch;
+    while (oPos < oEnd || nPos < nEnd) {
+      oSp.setLength(0);
+      nSp.setLength(0);
+      while (oPos < oEnd && isSpace(ch = oldV.charAt(oPos))) {
+        oSp.append(ch);
+        ++oPos;
+      }
+      while (nPos < nEnd && isSpace(ch = newV.charAt(nPos))) {
+        nSp.append(ch);
+        ++nPos;
+      }
+      diff += Math.abs(getNormalizedLength(options, oSp.toString())
+              - getNormalizedLength(options, nSp.toString())); //each time
+
+      while (oPos < oEnd && nPos < nEnd
+             && (ch = oldV.charAt(oPos)) == newV.charAt(nPos)
+             && !isSpace(ch)) {
+        ++oPos;
+        ++nPos;
+      }
+
+      if (oPos < oEnd && nPos < nEnd && !isSpace(oldV.charAt(oPos)) && !isSpace(newV.charAt(nPos))) {
+        logError("AST changed!");
+        return FDiffer.UGLY_FORMATTING;
+      }
+    }
+    return diff;
+  }
+
+  @Nullable
+  public static CustomCodeStyleSettings getLanguageSettings(@NotNull CodeStyleSettings settings, @NotNull Language language) {
+    for (CodeStyleSettingsProvider provider : CodeStyleSettingsProvider.EXTENSION_POINT_NAME.getExtensions()) {
+      if (language.equals(provider.getLanguage())) {
+        CustomCodeStyleSettings modelSettings = provider.createCustomSettings(settings);
+        if (modelSettings == null) continue;
+        CustomCodeStyleSettings customSettings = settings.getCustomSettings(modelSettings.getClass());
+        if (customSettings != null) {
+          return customSettings;
+        }
+      }
+    }
+    logError("Failed to load CustomCodeStyleSettings for " + language);
+    return null;
+  }
+
+  public static void adjustValuesMin(
+    @NotNull FValuesExtractionResult gens,
+    @NotNull FDiffer differ,
+    @Nullable ProgressIndicator indicator) {
+
+    final List<FValue> values = gens.getValues();
+    final int length = values.size();
+    int i = 0;
+    for (FValue value : values) {
+      if (indicator != null) {
+        indicator.checkCanceled();
+        indicator.setText2("Value:" + value.name);
+        indicator.setFraction(0.5 + 0.5 * i / length);
+      }
+
+      Object bestValue = value.value;
+      int bestScope = differ.getDifference(gens);
+      for (Object cnst : value.getPossibleValues()) {
+        if (cnst.equals(value.value)) {
+          continue;
+        }
+        value.value = cnst;
+        int diff = differ.getDifference(gens);
+        if (diff < bestScope) {
+          bestValue = cnst;
+          bestScope = diff;
+          value.state = FValue.STATE.SELECTED;
+        }
+        else if (diff > bestScope) {
+          value.state = FValue.STATE.SELECTED;
+        }
+      }
+      value.value = bestValue;
+      ++i;
+    }
+  }
+
+  public static void adjustValuesGA(
+    @NotNull FGens gens,
+    @NotNull FDiffer differ,
+    @Nullable ProgressIndicator indicator) {
+
+    FGeneration generation = FGeneration.createZeroGeneration(gens);
+    while (generation.tryAgain()) {
+      if (indicator != null) {
+        indicator.checkCanceled();
+      }
+      final int age = generation.getAge();
+      if (indicator != null) {
+        indicator.setText2(" age:" + age + "/" + generation.getParentKind());
+        indicator.setFraction(0.5 * age / FGeneration.GEN_COUNT);
+      }
+      generation = FGeneration.createNextGeneration(differ, generation);
+    }
+    gens.copyFrom(generation.getBestGens(differ));
+  }
+
+  static long rseed = 0;
+  static final long RAND_MAX_32 = ((1L << 31L) - 1L);
+  static final long RAND_MAX = ((1L << 15L) - 1L);
+
+  public static void resetRandom() {
+    rseed = 0;
+  }
+
+  public static long getRandom() {
+    rseed = (rseed * 214013 + 2531011) & RAND_MAX_32;
+    return rseed >> 16;
+  }
+
+  public static int getRandomLess(int count) {
+    final int ret = (int)(getRandom() * count / RAND_MAX);
+    if (ret >= count) return count - 1;
+    if (ret < 0) return 0;
+    return ret;
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FDiffer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FDiffer.java
new file mode 100644 (file)
index 0000000..dda19f8
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.differ;
+
+import com.intellij.psi.codeStyle.extractor.values.FValuesExtractionResult;
+
+public interface FDiffer {
+  int UGLY_FORMATTING = Integer.MAX_VALUE / 4;
+
+  int getDifference(FValuesExtractionResult values);
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FDifferBase.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FDifferBase.java
new file mode 100644 (file)
index 0000000..01fd19a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.differ;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.extractor.FUtils;
+import com.intellij.psi.codeStyle.extractor.values.FValuesExtractionResult;
+
+/**
+ * @author Roman.Shein
+ * @since 30.07.2015.
+ */
+public abstract class FDifferBase implements FDiffer {
+  protected final Project myProject;
+  protected final String myOrigText;
+  protected final CodeStyleSettings mySettings;
+  protected final PsiFile myFile;
+
+  public FDifferBase(Project project, PsiFile file, CodeStyleSettings settings) {
+    myProject = project;
+    myFile = file;
+    myOrigText = myFile.getText();
+    mySettings = settings;
+  }
+
+  public abstract String reformattedText();
+
+  @Override
+  public int getDifference(FValuesExtractionResult container) {
+    final FValuesExtractionResult orig = container.apply(true);
+    String newText = reformattedText();
+    int result = FUtils.getDiff(mySettings.getCommonSettings(myFile.getLanguage()).getIndentOptions(), myOrigText, newText);
+    orig.apply(false);
+    return result;
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FLangCodeStyleExtractor.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/differ/FLangCodeStyleExtractor.java
new file mode 100644 (file)
index 0000000..4114f69
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.differ;
+
+import com.intellij.lang.LanguageExtension;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+/**
+ * @author Roman.Shein
+ * @since 31.07.2015.
+ */
+public interface FLangCodeStyleExtractor {
+  LanguageExtension<FLangCodeStyleExtractor> EXTENSION =
+      new LanguageExtension<FLangCodeStyleExtractor>("com.intellij.lang.formatting.extractor");
+
+  @NotNull
+  FDiffer getDiffer(Project project, PsiFile psiFile, CodeStyleSettings settings);
+
+  @NotNull
+  Collection<FValue.VAR_KIND> getCustomVarKinds();
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FBruteForceProcessor.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FBruteForceProcessor.java
new file mode 100644 (file)
index 0000000..5135aee
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.processor;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.extractor.FUtils;
+import com.intellij.psi.codeStyle.extractor.differ.FDiffer;
+import com.intellij.psi.codeStyle.extractor.differ.FLangCodeStyleExtractor;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import com.intellij.psi.codeStyle.extractor.values.FValuesExtractionResult;
+import com.intellij.psi.codeStyle.extractor.values.FValuesExtractionResultImpl;
+
+import java.util.List;
+import java.util.Random;
+
+/**
+ * @author Roman.Shein
+ * @since 04.08.2015.
+ */
+public class FBruteForceProcessor extends FCodeStyleDeriveProcessor {
+
+  public FBruteForceProcessor(FLangCodeStyleExtractor langExtractor) {
+    super(langExtractor);
+  }
+
+  @Override
+  public FValuesExtractionResult runWithProgress(Project project, CodeStyleSettings settings, PsiFile file, ProgressIndicator indicator) {
+    List<FValue> values = getFormattingValues(settings, file.getLanguage());
+    FDiffer differ = myLangExtractor.getDiffer(project, file, settings);
+    FValuesExtractionResult container = new FValuesExtractionResultImpl(values);
+    FUtils.adjustValuesMin(container, differ, indicator);
+    return container;
+  }
+
+  public void randomizeSettings(CodeStyleSettings settings, Language language) {
+    List<FValue> values = getFormattingValues(settings, language);
+    Random rand = new Random();
+    for (FValue value : values) {
+      Object[] possible = value.getPossibleValues();
+      int index = rand.nextInt(possible.length);
+      value.value = possible[index];
+      value.write(false);
+    }
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FCodeStyleDeriveProcessor.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FCodeStyleDeriveProcessor.java
new file mode 100644 (file)
index 0000000..692a0e3
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.processor;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import com.intellij.psi.codeStyle.extractor.FUtils;
+import com.intellij.psi.codeStyle.extractor.differ.FLangCodeStyleExtractor;
+import com.intellij.psi.codeStyle.extractor.values.FClassSerializer;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import com.intellij.psi.codeStyle.extractor.values.FValuesExtractionResult;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+/**
+ * @author Roman.Shein
+ * @since 04.08.2015.
+ */
+public abstract class FCodeStyleDeriveProcessor {
+
+  protected final FLangCodeStyleExtractor myLangExtractor;
+
+  protected FCodeStyleDeriveProcessor(FLangCodeStyleExtractor langExtractor) {
+    myLangExtractor = langExtractor;
+  }
+
+  public abstract FValuesExtractionResult runWithProgress(Project project, CodeStyleSettings settings, PsiFile file,
+                                    ProgressIndicator indicator);
+
+  public Map<FValue, Object> backupValues(CodeStyleSettings settings, Language language) {
+    List<FValue> baseValues = getFormattingValues(settings, language);
+    Map<FValue, Object> res = ContainerUtil.newHashMap();
+    for (FValue baseValue: baseValues) {
+      res.put(baseValue, baseValue.value);
+    }
+    return res;
+  }
+
+  @NotNull
+  private Collection<FValue.VAR_KIND> getVarKinds() {
+    List<FValue.VAR_KIND> varKinds = new LinkedList<FValue.VAR_KIND>();
+    varKinds.addAll(myLangExtractor.getCustomVarKinds());
+    varKinds.addAll(Arrays.asList(FValue.VAR_KIND.defaultKinds));
+    return varKinds;
+  }
+
+  @NotNull
+  private FValue.VAR_KIND getVarKind(@NotNull String name,  @NotNull Object value) {
+    for (FValue.VAR_KIND varKind : getVarKinds()) {
+      if (varKind.accepts(name, value)) {
+        return varKind;
+      }
+    }
+    return FValue.VAR_KIND.NOTHING;
+  }
+
+  @NotNull
+  private List<FValue> readAll(@NotNull String instanceName, @NotNull Object instance) {
+    Class<?> cls = instance.getClass();
+    List<FValue> ret = new ArrayList<FValue>();
+    FClassSerializer serializer = new FClassSerializer(instanceName, instance);
+    for (Field field : cls.getDeclaredFields()) {
+      field = FClassSerializer.getPreparedField(field);
+      if (field == null || field.getName().endsWith("_FORCE")) continue;
+      try {
+        ret.add(buildFValue(field, instance, serializer));
+      }
+      catch (IllegalAccessException e) {
+        e.printStackTrace();
+      }
+    }
+    return ret;
+  }
+
+  @NotNull
+  private FValue buildFValue(@NotNull Field field,
+                             @NotNull Object instance,
+                             @NotNull FClassSerializer serializer) throws IllegalAccessException {
+    String name = field.getName();
+    Object value = field.get(instance);
+    FValue.VAR_KIND varKind = getVarKind(name, value);
+    return new FValue(name, value, serializer, varKind);
+  }
+
+  @NotNull
+  protected List<FValue> getFormattingValues(CodeStyleSettings settings, Language language) {
+
+    final CommonCodeStyleSettings commonSettings = settings.getCommonSettings(language);
+    CommonCodeStyleSettings.IndentOptions indentOptions = commonSettings.getIndentOptions();
+    if (indentOptions == null) {
+      FUtils.logError("IndentOptions from common settings are null; using indent options from settings.");
+      indentOptions = settings.getIndentOptions();
+    }
+    final Object languageSettings = FUtils.getLanguageSettings(settings, language);
+
+    List<FValue> values = readAll("commonSettings", commonSettings);
+    if (languageSettings != null) {
+      values.addAll(readAll("ocSettings", languageSettings));
+    }
+    final LanguageCodeStyleSettingsProvider provider = LanguageCodeStyleSettingsProvider.forLanguage(language);
+    if (provider != null) {
+      final Set<String> supportedFields = provider.getSupportedFields();
+      List<FValue> cvalues = new ArrayList<FValue>(values.size());
+      for (FValue value : values) {
+        if (supportedFields.contains(value.name)) {
+          cvalues.add(value);
+        }
+      }
+      values = cvalues;
+    }
+
+    if (indentOptions != null) {
+      List<FValue> valuesOrder = readAll("indentOptions", indentOptions);
+      valuesOrder.addAll(values);
+      return valuesOrder;
+    } else {
+      FUtils.logError("Not indent options detected.");
+      return values;
+    }
+  }
+
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FGenProcessor.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/processor/FGenProcessor.java
new file mode 100644 (file)
index 0000000..223a9da
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.processor;
+
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.extractor.FUtils;
+import com.intellij.psi.codeStyle.extractor.differ.FDiffer;
+import com.intellij.psi.codeStyle.extractor.differ.FLangCodeStyleExtractor;
+import com.intellij.psi.codeStyle.extractor.values.FGens;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author Roman.Shein
+ * @since 29.07.2015.
+ */
+public class FGenProcessor extends FCodeStyleDeriveProcessor{
+
+  private static DateFormat formatter = new SimpleDateFormat("mm:ss");
+
+  public FGenProcessor(FLangCodeStyleExtractor langExtractor) {
+    super(langExtractor);
+  }
+
+  @Override
+  public FGens runWithProgress(Project project, CodeStyleSettings settings, PsiFile file, ProgressIndicator indicator) {
+    final FGens origGens = new FGens(getFormattingValues(settings, file.getLanguage()));
+    final FGens forSelection = origGens.copy();
+
+    final FDiffer differ = myLangExtractor.getDiffer(project, file, settings);
+    forSelection.dropToInitial();
+    FUtils.resetRandom();
+
+    long startTime = System.nanoTime();
+    FUtils.adjustValuesGA(forSelection, differ, indicator);
+    reportResult("GA", forSelection, differ, startTime, file.getName());
+
+    startTime = System.nanoTime();
+    FUtils.adjustValuesMin(forSelection, differ, indicator);
+    reportResult("MIN", forSelection, differ, startTime, file.getName());
+
+    return forSelection;
+  }
+
+  private void reportResult(String label, FGens gens, FDiffer differ, long startTime, String fileName) {
+    Date date = new Date((System.nanoTime() - startTime) / 1000000);
+    System.out.println(fileName + ": " + label + " range:" + differ.getDifference(gens) + "  Execution Time: " + formatter.format(date));
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FClassSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FClassSerializer.java
new file mode 100644 (file)
index 0000000..138c406
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.values;
+
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+public class FClassSerializer {
+  @NotNull
+  private String myInstanceName;
+  @NotNull
+  private final Object myInstance;
+
+  public FClassSerializer(@NotNull String instanceName, @NotNull Object o) {
+    myInstanceName = instanceName;
+    myInstance = o;
+  }
+
+  @Nullable
+  public Object read(@NotNull String name) {
+    try {
+      final Field field = getPreparedField(myInstance.getClass().getField(name));
+      if (field == null) return null;
+      return field.get(myInstance);
+    }
+    catch (NoSuchFieldException e) {
+      e.printStackTrace();
+    }
+    catch (IllegalAccessException e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+
+  @Nullable
+  @Contract("_, _, false -> null")
+  public Object write(@NotNull String name, @NotNull Object value, boolean retPrevValue) {
+    try {
+      final Field field = getPreparedField(myInstance.getClass().getField(name));
+      if (field != null) {
+        Object ret = retPrevValue ? field.get(myInstance) : null;
+        field.set(myInstance, value);
+        return ret;
+      }
+    }
+    catch (NoSuchFieldException e) {
+      e.printStackTrace();
+    }
+    catch (IllegalAccessException e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+
+  @Nullable
+  public static Field getPreparedField(Field field) {
+    field.setAccessible(true);
+    Class<?> type = field.getType();
+    if ((field.getModifiers() & Modifier.STATIC) != 0) {
+      return null;
+    }
+    if (type != int.class && type != boolean.class) {
+      return null;
+    }
+    if (field.getName().startsWith("my")) {
+      return null;
+    }
+    return field;
+  }
+
+  @NotNull
+  public String getInstanceName() {
+    return myInstanceName;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o instanceof FClassSerializer) {
+      FClassSerializer other = (FClassSerializer) o;
+      return other.myInstance.equals(myInstance);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return myInstance.hashCode();
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FGeneration.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FGeneration.java
new file mode 100644 (file)
index 0000000..c7e8626
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.values;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.codeStyle.extractor.FUtils;
+import com.intellij.psi.codeStyle.extractor.differ.FDiffer;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class FGeneration {
+
+  private static int GENERATION_POOL_SIZE = 45;
+  private static int MUTATION_PER_GEN = 10;
+  public  static int GEN_COUNT = 40;
+  private List<FGens> myGensPool;
+  private int myAge;
+  private int myParentKind;
+
+  private FGeneration(@NotNull final FGens bestGens) {
+    myParentKind = -1;
+    myGensPool = new ArrayList<FGens>(GENERATION_POOL_SIZE);
+    for (int i = 0; i < GENERATION_POOL_SIZE; ++i) {
+      // the best goes as is
+      myGensPool.add(new FGens(bestGens).mutate(i == 0 ? 0 : MUTATION_PER_GEN));
+    }
+    myAge = 0;
+  }
+
+  private FGeneration(@NotNull FGeneration previous, int parentKind) {
+    myAge = previous.myAge + 1;
+    myParentKind = parentKind;
+    myGensPool = new ArrayList<FGens>(GENERATION_POOL_SIZE);
+    int mutationsCount = MUTATION_PER_GEN;
+    //if (myAge < 30) {
+    //  if (myAge < 5) {
+    //    mutationsCount = 50;
+    //  }
+    //  else if (myAge % 5 == 0) {
+    //    mutationsCount = 25;
+    //  }
+    //}
+    //else if (myAge < 40) {
+    //  mutationsCount = 10;
+    //}
+    //else if (myAge < 50) {
+    //  mutationsCount = 5;
+    //}
+
+    final int prevPullSize = previous.myGensPool.size();
+    for (int i = 0; i < GENERATION_POOL_SIZE; i++) {
+      int parent1 = 0, parent2 = 0, iterations = 0;
+      while (parent1 == parent2) {
+        parent1 = FUtils.getRandomLess(prevPullSize);//~ fitness?
+        parent2 = FUtils.getRandomLess(prevPullSize);
+        if (++iterations > 25) break;
+      }
+      myGensPool.add(FGens.breed(
+        previous.myGensPool.get(parent1),
+        previous.myGensPool.get(parent2),
+        mutationsCount));
+    }
+  }
+
+  public static FGeneration createZeroGeneration(@NotNull FGens gens) {
+    return new FGeneration(gens);
+  }
+
+  public static FGeneration createNextGeneration(FDiffer differ, @NotNull FGeneration previous) {
+    final int parentKind = previous.reduceToSize(differ, (int)(0.2 * previous.myGensPool.size()));
+    return previous.tryAgain() ? new FGeneration(previous, parentKind) : previous;
+  }
+
+  private int reduceToSize(FDiffer differ, int newPoolSize) {
+    List<Pair<Integer, Integer>> ranges = new ArrayList<Pair<Integer, Integer>>(myGensPool.size());
+
+    int i = 0;
+    for (final FGens gens : myGensPool) {
+      int range = differ.getDifference(gens);
+      ranges.add(Pair.create(range, i++));
+      if (range == 0) {
+        myAge = GEN_COUNT;
+        newPoolSize = 1;
+        break;
+      }
+    }
+
+    Collections.sort(ranges, new Comparator<Pair<Integer, Integer>>() {
+      @Override
+      public int compare(Pair<Integer, Integer> o1, Pair<Integer, Integer> o2) {
+        return o1.first - o2.first;
+      }
+    });
+
+    final ArrayList<FGens> gensPool = new ArrayList<FGens>(newPoolSize);
+    int count = 0;
+    int worseForward = 0;
+    for (final Pair<Integer, Integer> pair : ranges) {
+      if (count >= newPoolSize) {
+        break;
+      }
+      FGens gens = myGensPool.get(pair.second);
+      gensPool.add(gens);
+      ++count;
+      worseForward = pair.first;
+    }
+    myGensPool = gensPool;
+
+    return worseForward;
+  }
+
+  public boolean tryAgain() {
+    return myAge < GEN_COUNT;
+  }
+
+  public FGens getBestGens(FDiffer differ) {
+    reduceToSize(differ, 1);
+    return myGensPool.get(0);
+  }
+
+  public int getAge() {
+    return myAge;
+  }
+
+  public int getParentKind() {
+    return myParentKind;
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FGens.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FGens.java
new file mode 100644 (file)
index 0000000..33eb05d
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.values;
+
+import com.intellij.psi.codeStyle.extractor.FUtils;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FGens extends FValuesExtractionResultImpl {
+
+  public FGens(@NotNull List<FValue> values) {
+    super(values);
+  }
+
+  public FGens(@NotNull FGens gens) {
+    this(gens.copy().getValues());
+  }
+
+  public FGens mutate(int averageMutationCount) {
+    if (averageMutationCount > 0) {
+      // with mutation
+
+      int commonMutagen = 0;
+
+      for (FValue value : myValues) {
+        commonMutagen += value.getMutagenFactor();
+      }
+
+      for (FValue value : myValues) {
+        if (FUtils.getRandomLess(commonMutagen) < value.getMutagenFactor() * averageMutationCount) {
+          final Object[] possibleValues = value.getPossibleValues();
+          value.value = possibleValues[FUtils.getRandomLess(possibleValues.length)];
+        }
+      }
+    }
+    return this;
+  }
+
+  public FGens dropToInitial() {
+    final ArrayList<FValue> values = new ArrayList<FValue>();
+    for (FValue value : myValues) {
+      final Object[] possibleValues = value.getPossibleValues();
+      if (possibleValues.length > 0) {
+        value.value = possibleValues[0];
+      }
+    }
+    return this;
+  }
+
+  @NotNull
+  public FGens copy() {
+    final ArrayList<FValue> values = new ArrayList<FValue>();
+    for (FValue value : myValues) {
+      values.add(new FValue(value));
+    }
+    return new FGens(values);
+  }
+
+
+  public FGens diff(FGens newGens) {
+    final List<FValue> newValues = newGens.getValues();
+    final int size = myValues.size();
+    assert size == newValues.size();
+    final List<FValue> diff = new ArrayList<FValue>();
+    for (int i = 0; i < size; ++i) {
+      final FValue value = myValues.get(i);
+      final FValue newValue = newValues.get(i);
+      assert value.name.equals(newValue.name);
+      if (!value.value.equals(newValue.value)) {
+        diff.add(new FValue(value.name, value.value + "->" + newValue.value, value.serializer, value.kind));
+      }
+    }
+    return new FGens(diff);
+  }
+
+  @NotNull
+  public static FGens breed(@NotNull FGens p1, @NotNull FGens p2, int averageMutationCount) {
+    final int size = p1.myValues.size();
+    assert size == p2.myValues.size();
+
+    // Crossover!
+    final int crossover = size / 2;//FUtils.getRandomLess(size - 6) + 3;
+
+    final List<FValue> values = new ArrayList<FValue>(size);
+    for (int i = 0; i < size; ++i) {
+      final FValue value1 = p1.myValues.get(i);
+      final FValue value2 = p2.myValues.get(i);
+      if (value1.kind == FValue.VAR_KIND.INDENT) {
+        values.add(new FValue(value1));
+      }
+      else if (value1.kind == FValue.VAR_KIND.BRACE_STYLE) {
+        values.add(new FValue(value2));
+      }
+      else if ((i & 0x1) == 1) {
+        values.add(new FValue(value1));
+      }
+      else {
+        values.add(new FValue(value2));
+      }
+    }
+    return new FGens(values).mutate(averageMutationCount);
+  }
+
+  public void copyFrom(FGens gens) {
+    if (myValues == gens.myValues) {
+      return;
+    }
+    myValues.clear();
+    myValues.addAll(gens.myValues);
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValue.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValue.java
new file mode 100644 (file)
index 0000000..938c3b5
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.values;
+
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class FValue {
+  public enum STATE {
+    INIT,
+    SELECTED,
+    ANY
+  }
+
+  public static abstract class VAR_KIND {
+
+    public int getMutagenFactor() {
+      return 1;
+    }
+
+    @NotNull
+    private Object[] myPossibleValues;
+
+    VAR_KIND(@NotNull Object[] possibleValues) {
+      myPossibleValues = possibleValues;
+    }
+
+    @NotNull
+    public Object[] getPossibleValues() {
+      return myPossibleValues;
+    }
+
+    public abstract boolean accepts(@NotNull String name, @NotNull Object value);
+
+    @NotNull
+    private static Object[] getRMValues() {
+      int from = 10;
+      int to = 120;
+      Object[] ret = new Object[to - from + 1];
+      ret[0] = -1; //any
+      for (int i = to; i > from; --i) ret[i - from] = i;
+      return ret;
+    }
+
+    //----------------Default var kinds go here---------------------
+    public static final VAR_KIND RIGHT_MARGIN = new CLASS_BASED_VAR_KIND(getRMValues(), Integer.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return name.equals("RIGHT_MARGIN");
+      }
+      @Override
+      public int getMutagenFactor() {
+        return 0;
+      }
+    };
+
+    public static final VAR_KIND BLANK = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2}, Integer.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return name.contains("BLANK");
+      }
+      @Override
+      public int getMutagenFactor() {
+        return 2;
+      }
+    };
+
+    public static final VAR_KIND INDENT = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2, 3, 4, 5, 6, 7, 8}, Integer.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return name.contains("INDENT");
+      }
+      @Override
+      public int getMutagenFactor() {
+        return 7;
+      }
+    };
+
+    public static final VAR_KIND DEFAULT = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2, 3, 4, 5, 6, 7, 8}, Integer.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return true;
+      }
+    };
+
+    public static final VAR_KIND TAB_SIZE = new CLASS_BASED_VAR_KIND(new Object[]{2, 4, 8}, Integer.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return name.contains("TAB_SIZE");
+      }
+      @Override
+      public int getMutagenFactor() {
+        return 2;
+      }
+    };
+
+    public static final VAR_KIND WRAP = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2, 5}, Integer.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return name.endsWith("_WRAP");
+      }
+    };
+
+    public static final VAR_KIND BRACE_STYLE = new CLASS_BASED_VAR_KIND(new Object[]{1, 2, 3, 4, 5}, Integer.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return name.endsWith("BRACE_STYLE") || name.endsWith("BRACE_PLACEMENT");
+      }
+      @Override
+      public int getMutagenFactor() {
+        return 7;
+      }
+    };
+
+    public static final VAR_KIND KEEP = new CLASS_BASED_VAR_KIND(new Object[]{true, false}, Boolean.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return name.contains("KEEP");
+      }
+      @Override
+      public int getMutagenFactor() {
+        return 3;
+      }
+    };
+
+    public static final VAR_KIND BOOL = new CLASS_BASED_VAR_KIND(new Object[]{true, false}, Boolean.class) {
+      @Override
+      public boolean acceptsName(@NotNull String name) {
+        return true;
+      }
+    };
+
+    public static final VAR_KIND NOTHING = new VAR_KIND(new Object[]{}) {
+      @Override
+      public boolean accepts(@NotNull String name, @NotNull Object value) {
+        return true;
+      }
+    };
+
+    public static final VAR_KIND[] defaultKinds = {RIGHT_MARGIN, WRAP, BRACE_STYLE, TAB_SIZE, INDENT, BLANK, DEFAULT,
+        KEEP, BOOL, NOTHING};
+  }
+
+  public static abstract class CLASS_BASED_VAR_KIND extends VAR_KIND {
+
+    private final Class<?> myVarClass;
+
+    public CLASS_BASED_VAR_KIND(@NotNull Object[] possibleValues, @NotNull Class<?> varClass) {
+      super(possibleValues);
+      myVarClass = varClass;
+    }
+
+    @Override
+    public boolean accepts(@NotNull String name, @NotNull Object value) {
+      return value.getClass().equals(myVarClass) && acceptsName(name);
+    }
+
+    public abstract boolean acceptsName(@NotNull String name);
+  }
+
+  public Object[] getPossibleValues() {
+    return kind.getPossibleValues();
+  }
+
+  public int getMutagenFactor() {
+    return kind.getMutagenFactor();
+  }
+
+  @NotNull
+  public final String name;
+  @NotNull
+  public Object value;
+  @NotNull
+  public STATE state;
+  @NotNull
+  public FClassSerializer serializer;
+  @NotNull
+  public final VAR_KIND kind;
+
+  public FValue(@NotNull String name, @NotNull Object value, @NotNull FClassSerializer serializer, @NotNull VAR_KIND kind) {
+    this.kind = kind;
+    this.name = name;
+    if (value instanceof Integer && ((Integer)value) == 0 && kind == VAR_KIND.BRACE_STYLE) {
+      this.value = 1;
+    }
+    else {
+      this.value = value;
+    }
+
+    state = STATE.INIT;
+    this.serializer = serializer;
+  }
+
+  public FValue(@NotNull FValue valueZ) {
+    name = valueZ.name;
+    value = valueZ.value;
+    state = valueZ.state;
+    serializer = valueZ.serializer;
+    kind = valueZ.kind;
+  }
+
+  @Nullable
+  @Contract("false -> null")
+  public FValue write(boolean retPrevValue) {
+    final Object orig = serializer.write(name, value, retPrevValue);
+    return orig == null ? null : new FValue(name, orig, serializer, kind);
+  }
+
+  @Override
+  public String toString() {
+    return name + "=" + value + ";";
+  }
+
+  @Override
+  public int hashCode() {
+    return name.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o instanceof FValue) {
+      FValue other = (FValue) o;
+      return other.name.equals(name) && other.serializer.equals(serializer);
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValuesExtractionResult.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValuesExtractionResult.java
new file mode 100644 (file)
index 0000000..2021047
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.values;
+
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Roman.Shein
+ * @since 04.08.2015.
+ */
+public interface FValuesExtractionResult {
+
+  @NotNull
+  List<FValue> getValues();
+
+  void applySelected();
+
+  void applyConditioned(Condition<FValue> c, Map<FValue, Object> backup);
+
+  FValuesExtractionResult apply(boolean retPrevValue);
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValuesExtractionResultImpl.java b/platform/lang-api/src/com/intellij/psi/codeStyle/extractor/values/FValuesExtractionResultImpl.java
new file mode 100644 (file)
index 0000000..e17ba00
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.values;
+
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Roman.Shein
+ * @since 04.08.2015.
+ */
+public class FValuesExtractionResultImpl implements FValuesExtractionResult {
+  @NotNull
+  protected final List<FValue> myValues;
+
+  public FValuesExtractionResultImpl(@NotNull List<FValue> values) {
+    myValues = values;
+  }
+
+  @NotNull
+  public List<FValue> getValues() {
+    return myValues;
+  }
+
+  public void applySelected() {
+    for (FValue value : myValues) {
+      if (value.state == FValue.STATE.SELECTED) {
+        value.write(false);
+      }
+    }
+  }
+
+  @Override
+  public void applyConditioned(Condition<FValue> c, Map<FValue, Object> backup) {
+    for (FValue value: myValues) {
+      if (c.value(value)) {
+        value.write(false);
+      } else {
+        value.value = backup.get(value);
+        value.write(false);
+      }
+    }
+  }
+
+  @Contract("false -> null")
+  public FValuesExtractionResult apply(boolean retPrevValue) {
+    if (retPrevValue) {
+      final ArrayList<FValue> orig = new ArrayList<FValue>();
+      for (FValue value : myValues) {
+        final FValue old = value.write(true);
+        if (old != null) {
+          orig.add(old);
+        }
+      }
+      return new FGens(orig);
+    }
+
+    for (FValue value : myValues) {
+      value.write(false);
+    }
+    return null;
+  }
+}
index 761b7176ba04a219bbeae0d4ae6a45b884f3bd8c..5c295e7e3568f58d93b2d88d6cc6c2eb10876b86 100644 (file)
@@ -18,16 +18,14 @@ package com.intellij.application.options.codeStyle;
 import com.intellij.openapi.application.ApplicationBundle;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Trinity;
-import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
-import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
-import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import com.intellij.psi.codeStyle.*;
 import com.intellij.ui.OptionGroup;
 import com.intellij.ui.ScrollPaneFactory;
 import com.intellij.ui.components.JBLabel;
 import com.intellij.util.containers.MultiMap;
 import com.intellij.util.ui.UIUtil;
 import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
@@ -62,8 +60,10 @@ public class CodeStyleBlankLinesPanel extends CustomizableLanguageCodeStylePanel
 
     JPanel optionsPanel = new JPanel(new GridBagLayout());
 
-    OptionGroup keepBlankLinesOptionsGroup = createKeepBlankLinesOptionsGroup();
-    OptionGroup blankLinesOptionsGroup = createBlankLinesOptionsGroup();
+    Map<CodeStyleSettingRepresentation.SettingsGroup, List<CodeStyleSettingRepresentation>> settings = CodeStyleSettingRepresentation.getStandardSettings(getSettingsType());
+
+    OptionGroup keepBlankLinesOptionsGroup = createOptionsGroup(BLANK_LINES_KEEP, settings.get(new CodeStyleSettingRepresentation.SettingsGroup(BLANK_LINES_KEEP)));
+    OptionGroup blankLinesOptionsGroup = createOptionsGroup(BLANK_LINES, settings.get(new CodeStyleSettingRepresentation.SettingsGroup(BLANK_LINES)));
     if (keepBlankLinesOptionsGroup != null) {
       keepBlankLinesOptionsGroup.setAnchor(keepBlankLinesOptionsGroup.findAnchor());
       optionsPanel.add(keepBlankLinesOptionsGroup.createPanel(),
@@ -109,37 +109,13 @@ public class CodeStyleBlankLinesPanel extends CustomizableLanguageCodeStylePanel
   }
 
   @Nullable
-  private OptionGroup createBlankLinesOptionsGroup() {
-    OptionGroup optionGroup = new OptionGroup(BLANK_LINES);
-
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.package.statement"), "BLANK_LINES_BEFORE_PACKAGE");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.package.statement"), "BLANK_LINES_AFTER_PACKAGE");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.imports"), "BLANK_LINES_BEFORE_IMPORTS");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.imports"), "BLANK_LINES_AFTER_IMPORTS");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.class"), "BLANK_LINES_AROUND_CLASS");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.class.header"), "BLANK_LINES_AFTER_CLASS_HEADER");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.anonymous.class.header"),
-                 "BLANK_LINES_AFTER_ANONYMOUS_CLASS_HEADER");
-    createOption(optionGroup, "Around field in interface:", "BLANK_LINES_AROUND_FIELD_IN_INTERFACE");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.field"), "BLANK_LINES_AROUND_FIELD");
-    createOption(optionGroup, "Around method in interface:", "BLANK_LINES_AROUND_METHOD_IN_INTERFACE");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.method"), "BLANK_LINES_AROUND_METHOD");
-    createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.method.body"), "BLANK_LINES_BEFORE_METHOD_BODY");
-    initCustomOptions(optionGroup, BLANK_LINES);
-
-    if (optionGroup.getComponents().length == 0) return null;
+  private OptionGroup createOptionsGroup(@NotNull String groupName, @NotNull List<CodeStyleSettingRepresentation> settings) {
+    OptionGroup optionGroup = new OptionGroup(groupName);
 
-    return optionGroup;
-  }
-
-  @Nullable
-  private OptionGroup createKeepBlankLinesOptionsGroup() {
-    OptionGroup optionGroup = new OptionGroup(BLANK_LINES_KEEP);
-
-    createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.in.declarations"), "KEEP_BLANK_LINES_IN_DECLARATIONS");
-    createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.in.code"), "KEEP_BLANK_LINES_IN_CODE");
-    createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.before.rbrace"), "KEEP_BLANK_LINES_BEFORE_RBRACE");
-    initCustomOptions(optionGroup, BLANK_LINES_KEEP);
+    for (CodeStyleSettingRepresentation setting: settings) {
+      createOption(optionGroup, setting.getUiName(), setting.getFieldName());
+    }
+    initCustomOptions(optionGroup, groupName);
 
     if (optionGroup.getComponents().length == 0) return null;
 
index be4ef0ddd131bfde8906987006a9c3fe76224b44..da27978fae3a7ff66ccf7767a05d034457fda3d6 100644 (file)
 package com.intellij.application.options.codeStyle;
 
 import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.psi.codeStyle.CodeStyleSettingRepresentation;
 import com.intellij.psi.codeStyle.CodeStyleSettings;
 import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
 
+import java.util.List;
+import java.util.Map;
+
 public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
   public CodeStyleSpacesPanel(CodeStyleSettings settings) {
     super(settings);
@@ -32,100 +36,15 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
 
   @Override
   protected void initTables() {
-    initBooleanField("SPACE_BEFORE_METHOD_PARENTHESES", ApplicationBundle.message("checkbox.spaces.method.declaration.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_METHOD_CALL_PARENTHESES", ApplicationBundle.message("checkbox.spaces.method.call.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_WHILE_PARENTHESES", ApplicationBundle.message("checkbox.spaces.while.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_SWITCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.switch.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_CATCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.catch.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_SYNCHRONIZED_PARENTHESES", ApplicationBundle.message("checkbox.spaces.synchronized.parentheses"), SPACES_BEFORE_PARENTHESES);
-    initBooleanField("SPACE_BEFORE_ANOTATION_PARAMETER_LIST", ApplicationBundle.message("checkbox.spaces.annotation.parameters"), SPACES_BEFORE_PARENTHESES);
-    initCustomOptions(SPACES_BEFORE_PARENTHESES);
-
-    initBooleanField("SPACE_AROUND_ASSIGNMENT_OPERATORS", ApplicationBundle.message("checkbox.spaces.assignment.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_LOGICAL_OPERATORS", ApplicationBundle.message("checkbox.spaces.logical.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_EQUALITY_OPERATORS", ApplicationBundle.message("checkbox.spaces.equality.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_RELATIONAL_OPERATORS", ApplicationBundle.message("checkbox.spaces.relational.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_BITWISE_OPERATORS", ApplicationBundle.message("checkbox.spaces.bitwise.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_ADDITIVE_OPERATORS", ApplicationBundle.message("checkbox.spaces.additive.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_MULTIPLICATIVE_OPERATORS", ApplicationBundle.message("checkbox.spaces.multiplicative.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_SHIFT_OPERATORS", ApplicationBundle.message("checkbox.spaces.shift.operators"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_UNARY_OPERATOR", ApplicationBundle.message("checkbox.spaces.around.unary.operator"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_LAMBDA_ARROW", ApplicationBundle.message("checkbox.spaces.around.lambda.arrow"), SPACES_AROUND_OPERATORS);
-    initBooleanField("SPACE_AROUND_METHOD_REF_DBL_COLON", ApplicationBundle.message("checkbox.spaces.around.method.ref.dbl.colon.arrow"), SPACES_AROUND_OPERATORS);
-    initCustomOptions(SPACES_AROUND_OPERATORS);
-
-    initBooleanField("SPACE_BEFORE_CLASS_LBRACE", ApplicationBundle.message("checkbox.spaces.class.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_METHOD_LBRACE", ApplicationBundle.message("checkbox.spaces.method.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_IF_LBRACE", ApplicationBundle.message("checkbox.spaces.if.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_ELSE_LBRACE", ApplicationBundle.message("checkbox.spaces.else.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_FOR_LBRACE", ApplicationBundle.message("checkbox.spaces.for.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_WHILE_LBRACE", ApplicationBundle.message("checkbox.spaces.while.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_DO_LBRACE", ApplicationBundle.message("checkbox.spaces.do.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_SWITCH_LBRACE", ApplicationBundle.message("checkbox.spaces.switch.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_TRY_LBRACE", ApplicationBundle.message("checkbox.spaces.try.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_CATCH_LBRACE", ApplicationBundle.message("checkbox.spaces.catch.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_FINALLY_LBRACE", ApplicationBundle.message("checkbox.spaces.finally.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_SYNCHRONIZED_LBRACE", ApplicationBundle.message("checkbox.spaces.synchronized.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE", ApplicationBundle.message("checkbox.spaces.array.initializer.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initBooleanField("SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE", ApplicationBundle.message("checkbox.spaces.annotation.array.initializer.left.brace"), SPACES_BEFORE_LEFT_BRACE);
-    initCustomOptions(SPACES_BEFORE_LEFT_BRACE);
-
-    initBooleanField("SPACE_BEFORE_ELSE_KEYWORD", ApplicationBundle.message("checkbox.spaces.else.keyword"), SPACES_BEFORE_KEYWORD);
-    initBooleanField("SPACE_BEFORE_WHILE_KEYWORD", ApplicationBundle.message("checkbox.spaces.while.keyword"), SPACES_BEFORE_KEYWORD);
-    initBooleanField("SPACE_BEFORE_CATCH_KEYWORD", ApplicationBundle.message("checkbox.spaces.catch.keyword"), SPACES_BEFORE_KEYWORD);
-    initBooleanField("SPACE_BEFORE_FINALLY_KEYWORD", ApplicationBundle.message("checkbox.spaces.finally.keyword"), SPACES_BEFORE_KEYWORD);
-    initCustomOptions(SPACES_BEFORE_KEYWORD);
-
-    initBooleanField("SPACE_WITHIN_BRACES", ApplicationBundle.message("checkbox.spaces.within.braces"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_BRACKETS", ApplicationBundle.message("checkbox.spaces.within.brackets"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_ARRAY_INITIALIZER_BRACES", ApplicationBundle.message("checkbox.spaces.within.array.initializer.braces"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_EMPTY_ARRAY_INITIALIZER_BRACES", ApplicationBundle.message("checkbox.spaces.within.empty.array.initializer.braces"), SPACES_WITHIN);
-
-    initBooleanField("SPACE_WITHIN_PARENTHESES", ApplicationBundle.message("checkbox.spaces.within.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_METHOD_CALL_PARENTHESES", ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.call.parentheses"), SPACES_WITHIN);
-    initBooleanField(
-      "SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES",
-      ApplicationBundle.message("checkbox.spaces.checkbox.spaces.empty.method.call.parentheses"),
-      SPACES_WITHIN
-    );
-    initBooleanField("SPACE_WITHIN_METHOD_PARENTHESES", ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.declaration.parentheses"), SPACES_WITHIN);
-    initBooleanField(
-      "SPACE_WITHIN_EMPTY_METHOD_PARENTHESES",
-      ApplicationBundle.message("checkbox.spaces.checkbox.spaces.empty.method.declaration.parentheses"),
-      SPACES_WITHIN
-    );
-    initBooleanField("SPACE_WITHIN_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_WHILE_PARENTHESES", ApplicationBundle.message("checkbox.spaces.while.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_SWITCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.switch.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_CATCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.catch.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_SYNCHRONIZED_PARENTHESES", ApplicationBundle.message("checkbox.spaces.synchronized.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_CAST_PARENTHESES", ApplicationBundle.message("checkbox.spaces.type.cast.parentheses"), SPACES_WITHIN);
-    initBooleanField("SPACE_WITHIN_ANNOTATION_PARENTHESES", ApplicationBundle.message("checkbox.spaces.annotation.parentheses"), SPACES_WITHIN);
-    initCustomOptions(SPACES_WITHIN);
-
-    initBooleanField("SPACE_BEFORE_QUEST", ApplicationBundle.message("checkbox.spaces.before.question"), SPACES_IN_TERNARY_OPERATOR);
-    initBooleanField("SPACE_AFTER_QUEST", ApplicationBundle.message("checkbox.spaces.after.question"), SPACES_IN_TERNARY_OPERATOR);
-    initBooleanField("SPACE_BEFORE_COLON", ApplicationBundle.message("checkbox.spaces.before.colon"), SPACES_IN_TERNARY_OPERATOR);
-    initBooleanField("SPACE_AFTER_COLON", ApplicationBundle.message("checkbox.spaces.after.colon"), SPACES_IN_TERNARY_OPERATOR);
-    initCustomOptions(SPACES_IN_TERNARY_OPERATOR);
-
-    initBooleanField("SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS", ApplicationBundle.message("checkbox.spaces.after.comma"), SPACES_WITHIN_TYPE_ARGUMENTS);
-    initCustomOptions(SPACES_WITHIN_TYPE_ARGUMENTS);
-
-    initCustomOptions(SPACES_IN_TYPE_ARGUMENTS);
-    initCustomOptions(SPACES_IN_TYPE_PARAMETERS);
-
-    initBooleanField("SPACE_BEFORE_COMMA", ApplicationBundle.message("checkbox.spaces.before.comma"), SPACES_OTHER);
-    initBooleanField("SPACE_AFTER_COMMA", ApplicationBundle.message("checkbox.spaces.after.comma"), SPACES_OTHER);
-    initBooleanField("SPACE_BEFORE_SEMICOLON", ApplicationBundle.message("checkbox.spaces.before.semicolon"), SPACES_OTHER);
-    initBooleanField("SPACE_AFTER_SEMICOLON", ApplicationBundle.message("checkbox.spaces.after.semicolon"), SPACES_OTHER);
-    initBooleanField("SPACE_AFTER_TYPE_CAST", ApplicationBundle.message("checkbox.spaces.after.type.cast"), SPACES_OTHER);
-    initCustomOptions(SPACES_OTHER);
+    Map<CodeStyleSettingRepresentation.SettingsGroup, List<CodeStyleSettingRepresentation>> settingsMap = CodeStyleSettingRepresentation.getStandardSettings(getSettingsType());
+
+    for (Map.Entry<CodeStyleSettingRepresentation.SettingsGroup, List<CodeStyleSettingRepresentation>> entry: settingsMap.entrySet()) {
+      String groupName = entry.getKey().name;
+      for (CodeStyleSettingRepresentation setting: entry.getValue()) {
+        initBooleanField(setting.getFieldName(), setting.getUiName(), groupName);
+      }
+      initCustomOptions(groupName);
+    }
   }
 
   @Override
index 6f8e536daba2c4959ea108b054fd75dc7d71653d..7c64542ed8b63a3243ca8379c739b6138a48e9e8 100644 (file)
@@ -16,9 +16,7 @@
 package com.intellij.application.options.codeStyle;
 
 import com.intellij.openapi.application.ApplicationBundle;
-import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
-import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
+import com.intellij.psi.codeStyle.*;
 import com.intellij.ui.SpeedSearchComparator;
 import com.intellij.ui.TreeTableSpeedSearch;
 import com.intellij.ui.components.JBCheckBox;
@@ -283,7 +281,7 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
     return result == null ? defaultName : result;
   }
 
-  private static void expandTree(final JTree tree) {
+  public static void expandTree(final JTree tree) {
     int oldRowCount = 0;
     do {
       int rowCount = tree.getRowCount();
index 66b398a8325088d7108f7a6f2180767622201bef..42bc9448f6fe66ab35b5e18dd8c4f07f8c817cd5 100644 (file)
 package com.intellij.application.options.codeStyle;
 
 import com.intellij.openapi.application.ApplicationBundle;
-import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import com.intellij.psi.codeStyle.*;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -60,110 +60,26 @@ public class WrappingAndBracesPanel extends OptionTableWithPreviewPanel {
 
   @Override
   protected void initTables() {
-    addOption("RIGHT_MARGIN", ApplicationBundle.message("editbox.right.margin.columns"), null, 0, 999, -1, ApplicationBundle.message("settings.code.style.default.general"));
-    addOption("WRAP_ON_TYPING", ApplicationBundle.message("wrapping.wrap.on.typing"), null, WRAP_ON_TYPING_OPTIONS, WRAP_ON_TYPING_VALUES);
-    
-    addOption("KEEP_LINE_BREAKS", ApplicationBundle.message("wrapping.keep.line.breaks"), WRAPPING_KEEP);
-    addOption("KEEP_FIRST_COLUMN_COMMENT", ApplicationBundle.message("wrapping.keep.comment.at.first.column"), WRAPPING_KEEP);
-    addOption("KEEP_CONTROL_STATEMENT_IN_ONE_LINE", ApplicationBundle.message("checkbox.keep.when.reformatting.control.statement.in.one.line"), WRAPPING_KEEP);
-    addOption("KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.multiple.expressions.in.one.line"), WRAPPING_KEEP);
-    addOption("KEEP_SIMPLE_BLOCKS_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.simple.blocks.in.one.line"), WRAPPING_KEEP);
-    addOption("KEEP_SIMPLE_METHODS_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.simple.methods.in.one.line"), WRAPPING_KEEP);
-    addOption("KEEP_SIMPLE_CLASSES_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.simple.classes.in.one.line"), WRAPPING_KEEP);
-
-    addOption("WRAP_LONG_LINES", ApplicationBundle.message("wrapping.long.lines"), null);
-    addOption("WRAP_COMMENTS", ApplicationBundle.message("wrapping.comments.wrap.at.right.margin"), WRAPPING_COMMENTS);
-
-    addOption("CLASS_BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.class.declaration"), WRAPPING_BRACES, BRACE_PLACEMENT_OPTIONS, BRACE_PLACEMENT_VALUES);
-    addOption("METHOD_BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.method.declaration"), WRAPPING_BRACES, BRACE_PLACEMENT_OPTIONS, BRACE_PLACEMENT_VALUES);
-    addOption("BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.other"), WRAPPING_BRACES, BRACE_PLACEMENT_OPTIONS, BRACE_PLACEMENT_VALUES);
-
-    addOption("EXTENDS_LIST_WRAP", WRAPPING_EXTENDS_LIST, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_EXTENDS_LIST", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_EXTENDS_LIST);
-
-    addOption("EXTENDS_KEYWORD_WRAP", WRAPPING_EXTENDS_KEYWORD, WRAP_OPTIONS_FOR_SINGLETON, WRAP_VALUES_FOR_SINGLETON);
-
-    addOption("THROWS_LIST_WRAP", WRAPPING_THROWS_LIST, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_THROWS_LIST", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_THROWS_LIST);
-    addOption("ALIGN_THROWS_KEYWORD", ApplicationBundle.message("wrapping.align.throws.keyword"), WRAPPING_THROWS_LIST);
-    addOption("THROWS_KEYWORD_WRAP", WRAPPING_THROWS_KEYWORD, WRAP_OPTIONS_FOR_SINGLETON, WRAP_VALUES_FOR_SINGLETON);
-
-    addOption("METHOD_PARAMETERS_WRAP", WRAPPING_METHOD_PARAMETERS, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_PARAMETERS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_METHOD_PARAMETERS);
-    addOption("METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_METHOD_PARAMETERS);
-    addOption("METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_METHOD_PARAMETERS);
-
-    addOption("CALL_PARAMETERS_WRAP", WRAPPING_METHOD_ARGUMENTS_WRAPPING, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_PARAMETERS_IN_CALLS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
-    addOption("PREFER_PARAMETERS_WRAP", ApplicationBundle.message("wrapping.take.priority.over.call.chain.wrapping"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
-    addOption("CALL_PARAMETERS_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
-    addOption("CALL_PARAMETERS_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
-
-    addOption("ALIGN_MULTILINE_METHOD_BRACKETS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_METHOD_PARENTHESES);
-
-    addOption("METHOD_CALL_CHAIN_WRAP", WRAPPING_CALL_CHAIN, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("WRAP_FIRST_METHOD_IN_CALL_CHAIN", ApplicationBundle.message("wrapping.chained.method.call.first.on.new.line"), WRAPPING_CALL_CHAIN);
-    addOption("ALIGN_MULTILINE_CHAINED_METHODS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_CALL_CHAIN);
-
-    addOption("IF_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_IF_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
-    addOption("ELSE_ON_NEW_LINE", ApplicationBundle.message("wrapping.else.on.new.line"), WRAPPING_IF_STATEMENT);
-    addOption("SPECIAL_ELSE_IF_TREATMENT", ApplicationBundle.message("wrapping.special.else.if.braces.treatment"), WRAPPING_IF_STATEMENT);
-
-    addOption("FOR_STATEMENT_WRAP", WRAPPING_FOR_STATEMENT, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_FOR", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_FOR_STATEMENT);
-    addOption("FOR_STATEMENT_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_FOR_STATEMENT);
-    addOption("FOR_STATEMENT_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_FOR_STATEMENT);
-    addOption("FOR_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_FOR_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
-
-    addOption("WHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_WHILE_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
-    addOption("DOWHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_DOWHILE_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
-    addOption("WHILE_ON_NEW_LINE", ApplicationBundle.message("wrapping.while.on.new.line"), WRAPPING_DOWHILE_STATEMENT);
-
-    addOption("INDENT_CASE_FROM_SWITCH", ApplicationBundle.message("wrapping.indent.case.from.switch"), WRAPPING_SWITCH_STATEMENT);
-    addOption("INDENT_BREAK_FROM_CASE", ApplicationBundle.message("wrapping.indent.break.from.case"), WRAPPING_SWITCH_STATEMENT);
-
-    addOption("RESOURCE_LIST_WRAP", WRAPPING_TRY_RESOURCE_LIST, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_RESOURCES", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_TRY_RESOURCE_LIST);
-    addOption("RESOURCE_LIST_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_TRY_RESOURCE_LIST);
-    addOption("RESOURCE_LIST_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_TRY_RESOURCE_LIST);
-
-    addOption("CATCH_ON_NEW_LINE", ApplicationBundle.message("wrapping.catch.on.new.line"), WRAPPING_TRY_STATEMENT);
-    addOption("FINALLY_ON_NEW_LINE", ApplicationBundle.message("wrapping.finally.on.new.line"), WRAPPING_TRY_STATEMENT);
-
-    addOption("BINARY_OPERATION_WRAP", WRAPPING_BINARY_OPERATION, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_BINARY_OPERATION", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_BINARY_OPERATION);
-    addOption("BINARY_OPERATION_SIGN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.operation.sign.on.next.line"), WRAPPING_BINARY_OPERATION);
-    addOption("ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION", ApplicationBundle.message("wrapping.align.parenthesised.when.multiline"), WRAPPING_BINARY_OPERATION);
-    addOption("PARENTHESES_EXPRESSION_LPAREN_WRAP", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_BINARY_OPERATION);
-    addOption("PARENTHESES_EXPRESSION_RPAREN_WRAP", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_BINARY_OPERATION);
-
-    addOption("ASSIGNMENT_WRAP", WRAPPING_ASSIGNMENT, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_ASSIGNMENT", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_ASSIGNMENT);
-    addOption("PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.assignment.sign.on.next.line"), WRAPPING_ASSIGNMENT);
-
-    addOption("ALIGN_GROUP_FIELD_DECLARATIONS", ApplicationBundle.message("wrapping.align.fields.in.columns"), WRAPPING_FIELDS_VARIABLES_GROUPS);
-    addOption("ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS", ApplicationBundle.message("wrapping.align.variables.in.columns"), WRAPPING_FIELDS_VARIABLES_GROUPS);
-
-    addOption("TERNARY_OPERATION_WRAP", WRAPPING_TERNARY_OPERATION, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_TERNARY_OPERATION", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_TERNARY_OPERATION);
-    addOption("TERNARY_OPERATION_SIGNS_ON_NEXT_LINE", ApplicationBundle.message("wrapping.quest.and.colon.signs.on.next.line"), WRAPPING_TERNARY_OPERATION);
-
-    addOption("ARRAY_INITIALIZER_WRAP", WRAPPING_ARRAY_INITIALIZER, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_ARRAY_INITIALIZER);
-    addOption("ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lbrace"), WRAPPING_ARRAY_INITIALIZER);
-    addOption("ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rbrace.on.new.line"), WRAPPING_ARRAY_INITIALIZER);
-
-    addOption("MODIFIER_LIST_WRAP", ApplicationBundle.message("wrapping.after.modifier.list"), WRAPPING_MODIFIER_LIST);
-
-    addOption("ASSERT_STATEMENT_WRAP", WRAPPING_ASSERT_STATEMENT, WRAP_OPTIONS, WRAP_VALUES);
-    addOption("ASSERT_STATEMENT_COLON_ON_NEXT_LINE", ApplicationBundle.message("wrapping.colon.signs.on.next.line"), WRAPPING_ASSERT_STATEMENT);
-
-    addOption("ENUM_CONSTANTS_WRAP", ApplicationBundle.message("wrapping.enum.constants"), WRAP_OPTIONS, WRAP_VALUES);
-    addOption("CLASS_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.classes.annotation"), WRAP_OPTIONS, WRAP_VALUES);
-    addOption("METHOD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.methods.annotation"), WRAP_OPTIONS, WRAP_VALUES);
-    addOption("FIELD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.fields.annotation"), WRAP_OPTIONS, WRAP_VALUES);
-    addOption("PARAMETER_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.parameters.annotation"), WRAP_OPTIONS, WRAP_VALUES);
-    addOption("VARIABLE_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.local.variables.annotation"), WRAP_OPTIONS, WRAP_VALUES);
+    for (Map.Entry<CodeStyleSettingRepresentation.SettingsGroup, List<CodeStyleSettingRepresentation>> entry:
+      CodeStyleSettingRepresentation.getStandardSettings(getSettingsType()).entrySet()) {
+      CodeStyleSettingRepresentation.SettingsGroup group = entry.getKey();
+      for (CodeStyleSettingRepresentation setting: entry.getValue()) {
+        //TODO this is ugly, but is the fastest way to make Options UI API and settings representation API connect
+        String fieldName = setting.getFieldName();
+        String uiName = setting.getUiName();
+        if (setting instanceof CodeStyleIntegerSettingRepresentation) {
+          CodeStyleIntegerSettingRepresentation intSetting = (CodeStyleIntegerSettingRepresentation) setting;
+          int defaultValue = intSetting.getDefaultValue();
+          addOption(fieldName, uiName, group.name, intSetting.getLowerBound(), intSetting.getUpperBound(), defaultValue, intSetting.getValueUiName(
+            defaultValue));
+        } else if (setting instanceof CodeStyleSelectSettingRepresentation) {
+          CodeStyleSelectSettingRepresentation selectSetting = (CodeStyleSelectSettingRepresentation) setting;
+          addOption(fieldName, uiName, group.name, selectSetting.getOptions(), selectSetting.getValues());
+        } else {
+          addOption(fieldName, uiName, group.name);
+        }
+      }
+    }
   }
 
   protected SettingsGroup getAssociatedSettingsGroup(String fieldName) {
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/FExtractCodeStyleAction.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/FExtractCodeStyleAction.java
new file mode 100644 (file)
index 0000000..211d21c
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageFormatting;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.openapi.wm.WindowManager;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.*;
+import com.intellij.psi.codeStyle.extractor.differ.FLangCodeStyleExtractor;
+import com.intellij.psi.codeStyle.extractor.ui.FExtractedSettingsDialog;
+import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemesImpl;
+import com.intellij.ui.BalloonLayout;
+import com.intellij.psi.codeStyle.extractor.processor.FCodeStyleDeriveProcessor;
+import com.intellij.psi.codeStyle.extractor.processor.FGenProcessor;
+import com.intellij.psi.codeStyle.extractor.ui.FCodeStyleSettingsNameProvider;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import com.intellij.psi.codeStyle.extractor.values.FValuesExtractionResult;
+import org.jetbrains.annotations.NotNull;
+
+
+import javax.swing.*;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import java.awt.*;
+import java.util.List;
+import java.util.Map;
+
+public class FExtractCodeStyleAction extends AnAction implements DumbAware {
+
+  @Override
+  public void actionPerformed(AnActionEvent e) {
+    DataContext dataContext = e.getDataContext();
+    final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+    if (project == null) return;
+    Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
+    final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
+    PsiFile file;
+    if (editor == null && files != null && files.length == 1 && !files[0].isDirectory()) {
+      file = PsiManager.getInstance(project).findFile(files[0]);
+    } else {
+      file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+    }
+    if (file == null) return;
+
+    Language language = file.getLanguage();
+
+    final FLangCodeStyleExtractor extractor = FLangCodeStyleExtractor.EXTENSION.forLanguage(language);
+    if (extractor == null) return;
+
+    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
+
+    final FCodeStyleDeriveProcessor genProcessor = new FGenProcessor(extractor);
+
+    final PsiFile finalFile = file;
+    final Task.Backgroundable task = new Task.Backgroundable(project, "Code style extractor", true) {
+      @Override
+      public void run(@NotNull ProgressIndicator indicator) {
+        try {
+          CodeStyleSettings cloneSettings = settings.clone();
+
+          Map<FValue, Object> backup = genProcessor.backupValues(cloneSettings, finalFile.getLanguage());
+
+          FValuesExtractionResult res = genProcessor.runWithProgress(project, cloneSettings, finalFile, indicator);
+
+          reportResult(res, project, cloneSettings, finalFile, backup);
+        }
+        catch (ProcessCanceledException e) {
+          FUtils.logError("Code extraction was canceled");
+        }
+        catch (Throwable t) {
+          t.printStackTrace();
+        }
+      }
+    };
+    ProgressManager.getInstance().run(task);
+  }
+
+  public void reportResult(final FValuesExtractionResult forSelection, final Project project,
+                           final CodeStyleSettings cloneSettings, final PsiFile file, final Map<FValue, Object> backup) {
+    final Balloon balloon = JBPopupFactory.getInstance()
+        .createHtmlTextBalloonBuilder(
+            "Formatting Options were extracted<br/><a href=\"apply\">Apply</a> <a href=\"details\">Details...</a>",
+            MessageType.INFO,
+            new HyperlinkListener() {
+              @Override
+              public void hyperlinkUpdate(HyperlinkEvent e) {
+                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+                  boolean apply = "apply".equals(e.getDescription());
+                  FExtractedSettingsDialog myDialog = null;
+                  if (!apply) {
+                    //@NonNls StringBuilder descriptions = new StringBuilder("<html>Set formatting options:");
+                    final List<FValue> values = forSelection.getValues();
+                    final LanguageCodeStyleSettingsProvider[] providers = Extensions.getExtensions(
+                      LanguageCodeStyleSettingsProvider.EP_NAME);
+                    Language language = file.getLanguage();
+                    FCodeStyleSettingsNameProvider nameProvider = new FCodeStyleSettingsNameProvider();
+                    for (final LanguageCodeStyleSettingsProvider provider : providers) {
+                      Language target = provider.getLanguage();
+                      if (target.equals(language)) {
+                        //this is our language
+                        nameProvider.addSettings(provider);
+                        myDialog = new FExtractedSettingsDialog(project, nameProvider, values);
+                        apply = myDialog.showAndGet();
+                        break;
+                      }
+                    }
+                    }
+                    if (apply && myDialog != null) {
+                      //create new settings named after the file
+                      final FExtractedSettingsDialog finalMyDialog = myDialog;
+                      forSelection.applyConditioned(new Condition<FValue>() {
+                        @Override
+                        public boolean value(FValue value) {
+                          return finalMyDialog.valueIsSelectedInTree(value);
+                        }
+                      }, backup);
+                      CodeStyleScheme derivedScheme = CodeStyleSchemes.getInstance().createNewScheme("Derived from " + file.getName(), null);
+                      derivedScheme.getCodeStyleSettings().copyFrom(cloneSettings);
+                      CodeStyleSchemes.getInstance().addScheme(derivedScheme);
+                      ((CodeStyleSchemesImpl) CodeStyleSchemes.getInstance()).getSchemeManager().setCurrent(derivedScheme);
+                      CodeStyleSettingsManager.getInstance(project).PREFERRED_PROJECT_CODE_STYLE = derivedScheme.getName();
+                    }
+                  }
+
+                }
+              }
+              ).setDisposable(ApplicationManager.getApplication()).setShowCallout(false).setFadeoutTime(0).
+              setShowCallout(false).setAnimationCycle(0).setHideOnClickOutside(false).setHideOnKeyOutside(false).
+              setCloseButtonEnabled(true).setHideOnLinkClick(true).createBalloon();
+
+              ApplicationManager.getApplication().
+
+              invokeLater(new Runnable() {
+                @Override
+                public void run () {
+                  Window window = WindowManager.getInstance().getFrame(project);
+                  if (window == null) {
+                    window = JOptionPane.getRootFrame();
+                  }
+                  if (window instanceof IdeFrame) {
+                    BalloonLayout layout = ((IdeFrame) window).getBalloonLayout();
+                    if (layout != null) {
+                      layout.add(balloon);
+                    }
+                  }
+                }
+              }
+
+              );
+            }
+
+    @Override
+    public void update(AnActionEvent event){
+      //TODO allow launch on file not opened in editor
+      Presentation presentation = event.getPresentation();
+      DataContext dataContext = event.getDataContext();
+      Project project = CommonDataKeys.PROJECT.getData(dataContext);
+      if (project == null){
+        presentation.setEnabled(false);
+        return;
+      }
+
+      Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
+
+      PsiFile file = null;
+      if (editor != null){
+        file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+      } else {
+        final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
+        if (files != null && files.length == 1 && !files[0].isDirectory()) {
+          file = PsiManager.getInstance(project).findFile(files[0]);
+        }
+      }
+
+      if (file == null || file.getVirtualFile() == null) {
+        presentation.setEnabled(false);
+        return;
+      }
+
+      if (LanguageFormatting.INSTANCE.forContext(file) != null) {
+        presentation.setEnabled(true);
+      }
+    }
+  }
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/ui/FCodeStyleSettingsNameProvider.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/ui/FCodeStyleSettingsNameProvider.java
new file mode 100644 (file)
index 0000000..79abb1b
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.ui;
+
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.codeStyle.*;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.psi.codeStyle.CodeStyleSettingRepresentation.SettingsGroup;
+import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider.SettingsType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Roman.Shein
+ * @since 03.08.2015.
+ */
+public class FCodeStyleSettingsNameProvider implements CodeStyleSettingsCustomizable {
+
+  protected Map<SettingsType, Map<SettingsGroup, List<CodeStyleSettingRepresentation>>> mySettings =
+    ContainerUtil.newHashMap();
+  private Map<SettingsType, Map<SettingsGroup, List<CodeStyleSettingRepresentation>>> standardSettings =
+    ContainerUtil.newHashMap();
+
+  public FCodeStyleSettingsNameProvider() {
+    for (SettingsType settingsType : SettingsType.values()) {
+      standardSettings.put(settingsType, CodeStyleSettingRepresentation.getStandardSettings(settingsType));
+    }
+  }
+
+  protected void addSetting(@NotNull SettingsGroup group, @NotNull CodeStyleSettingRepresentation setting, @Nullable OptionAnchor anchor,
+                            @Nullable String anchorFieldName) {
+    for (Map.Entry<SettingsType, Map<SettingsGroup, List<CodeStyleSettingRepresentation>>> entry: mySettings.entrySet()) {
+      if (entry.getValue().containsKey(group)) {
+        addSetting(entry.getKey(), group, setting, anchor, anchorFieldName);
+        return;
+      }
+    }
+    addSetting(SettingsType.LANGUAGE_SPECIFIC, group, setting, anchor, anchorFieldName);
+  }
+
+  protected void addSetting(@NotNull SettingsType settingsType, @NotNull SettingsGroup group, @NotNull CodeStyleSettingRepresentation setting,
+                            @Nullable OptionAnchor anchor, @Nullable String anchorFieldName) {
+    Map<CodeStyleSettingRepresentation.SettingsGroup, List<CodeStyleSettingRepresentation>> groups = mySettings.get(settingsType);
+    if (groups == null) {
+      groups = ContainerUtil.newLinkedHashMap();
+    }
+    List<CodeStyleSettingRepresentation> settingsList = groups.get(group);
+    if (settingsList == null) {
+      settingsList = ContainerUtil.newLinkedList();
+    }
+    if (settingsList.contains(setting)) return;
+    if (anchor != null && anchorFieldName != null) {
+      CodeStyleSettingRepresentation anchorSettingRepresentation = new CodeStyleSettingRepresentation(anchorFieldName, anchorFieldName);
+      int insertIndex = settingsList.indexOf(anchorSettingRepresentation);
+      if (insertIndex < 0) {
+        insertIndex = settingsList.size();
+      } else {
+        switch (anchor) {
+          case BEFORE:
+            break;
+          case AFTER:
+            insertIndex++;
+            break;
+          case NONE:
+            insertIndex = settingsList.size();
+        }
+      }
+      settingsList.add(insertIndex, setting);
+    } else {
+      settingsList.add(setting);
+    }
+    groups.put(group, settingsList);
+  }
+
+  @Override
+  public void showAllStandardOptions() {
+    for (SettingsType settingsType : SettingsType.values()) {
+      Map<SettingsGroup, List<CodeStyleSettingRepresentation>> standardGroups = standardSettings.get(settingsType);
+      for (Map.Entry<SettingsGroup, List<CodeStyleSettingRepresentation>> entry : standardGroups.entrySet()) {
+        for (CodeStyleSettingRepresentation setting: entry.getValue()) {
+          addSetting(settingsType, entry.getKey(), setting, null, null);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void showStandardOptions(String... optionNames) {
+    List<String> options = Arrays.asList(optionNames);
+    for (SettingsType settingsType : SettingsType.values()) {
+      Map<SettingsGroup, List<CodeStyleSettingRepresentation>> standardGroups = standardSettings.get(settingsType);
+      for (Map.Entry<SettingsGroup, List<CodeStyleSettingRepresentation>> entry : standardGroups.entrySet()) {
+        for (CodeStyleSettingRepresentation setting: entry.getValue()) {
+          if (options.contains(setting.getFieldName())) {
+            addSetting(settingsType, entry.getKey(), setting, null, null);
+          }
+        }
+      }
+    }
+  }
+
+  @Override
+  public void showCustomOption(Class<? extends CustomCodeStyleSettings> settingsClass, @NotNull String fieldName, @NotNull String title, @Nullable String groupName, Object... options) {
+    showCustomOption(settingsClass, fieldName, title, groupName, null, null, options);
+  }
+
+  @Override
+  public void showCustomOption(Class<? extends CustomCodeStyleSettings> settingsClass, @NotNull String fieldName, @NotNull String title,
+                               @Nullable String groupName, @Nullable OptionAnchor anchor, @Nullable String anchorFieldName, Object... options) {
+    if (options.length == 2) {
+      addSetting(new SettingsGroup(groupName), new CodeStyleSelectSettingRepresentation(fieldName, title, (int[])options[1],
+                                                                                        (String[])options[0]), anchor, anchorFieldName);
+    } else {
+      addSetting(new SettingsGroup(groupName), new CodeStyleSettingRepresentation(fieldName, title), anchor, anchorFieldName);
+    }
+  }
+
+  @Override
+  public void renameStandardOption(String fieldName, String newTitle) {
+    for (SettingsType settingsType : SettingsType.values()) {
+      Map<SettingsGroup, List<CodeStyleSettingRepresentation>> standardGroups = mySettings.get(settingsType);
+      if (standardGroups == null) {
+        continue;
+      }
+      for (Map.Entry<SettingsGroup, List<CodeStyleSettingRepresentation>> entry : standardGroups.entrySet()) {
+        for (CodeStyleSettingRepresentation setting: entry.getValue()) {
+          if (setting.getFieldName().equals(fieldName)) {
+            setting.setUiName(newTitle);
+            return;
+          }
+        }
+      }
+    }
+  }
+
+  @Override
+  public void moveStandardOption(String fieldName, String newGroup) {
+    for (SettingsType settingsType : SettingsType.values()) {
+      Map<SettingsGroup, List<CodeStyleSettingRepresentation>> standardGroups = mySettings.get(settingsType);
+      if (standardGroups == null) {
+        standardGroups = ContainerUtil.newLinkedHashMap();
+        mySettings.put(settingsType, standardGroups);
+      }
+      for (Map.Entry<SettingsGroup, List<CodeStyleSettingRepresentation>> entry : standardGroups.entrySet()) {
+        CodeStyleSettingRepresentation moveSetting = null;
+        for (CodeStyleSettingRepresentation setting: entry.getValue()) {
+          if (setting.getFieldName().equals(fieldName)) {
+            moveSetting = setting;
+            break;
+          }
+        }
+        if (moveSetting != null) {
+          entry.getValue().remove(moveSetting);
+          addSetting(new SettingsGroup(newGroup), moveSetting, null, null);
+        }
+      }
+    }
+  }
+
+  public static String getSettingsTypeName(LanguageCodeStyleSettingsProvider.SettingsType settingsType) {
+    switch (settingsType) {
+      case BLANK_LINES_SETTINGS: return ApplicationBundle.message("title.blank.lines");
+      case SPACING_SETTINGS: return ApplicationBundle.message("title.spaces");
+      case WRAPPING_AND_BRACES_SETTINGS: return ApplicationBundle.message("wrapping.and.braces");
+      case INDENT_SETTINGS: return ApplicationBundle.message("title.tabs.and.indents");
+      case LANGUAGE_SPECIFIC: return "Language-specific"; //TODO should load from ApplciationBundle here
+      default: throw new IllegalArgumentException("Unknown settings type: " + settingsType);
+    }
+  }
+
+  public void addSettings(LanguageCodeStyleSettingsProvider provider) {
+    for (SettingsType settingsType : LanguageCodeStyleSettingsProvider.SettingsType.values()) {
+      provider.customizeSettings(this, settingsType);
+    }
+  }
+
+  public static FValue getValue(final CodeStyleSettingRepresentation representation, List<FValue> values) {
+    FValue myValue = ContainerUtil.find(values, new Condition<FValue>() {
+      @Override
+      public boolean value(FValue value) {
+        return value.state == FValue.STATE.SELECTED && value.name.equals(representation.getFieldName());
+        //return value.name.equals(representation.getFieldName()); //TODO this is here only to test the UI!!
+      }
+    });
+    return myValue;
+  }
+
+  public String getSettings(List<FValue> values) {
+    StringBuilder builder = new StringBuilder();
+    for (SettingsType settingsType : LanguageCodeStyleSettingsProvider.SettingsType.values()) {
+      builder.append("<br><b><u>").append(getSettingsTypeName(settingsType)).append("</u></b>");
+      Map<SettingsGroup, List<CodeStyleSettingRepresentation>> groups = mySettings.get(settingsType);
+      if (groups != null) {
+        for (Map.Entry<SettingsGroup, List<CodeStyleSettingRepresentation>> entry : groups.entrySet()) {
+          boolean firstSettingGroupTop = entry.getKey().isNull();
+          boolean groupReported = false;
+          for (final CodeStyleSettingRepresentation setting : entry.getValue()) {
+            FValue myValue = ContainerUtil.find(values, new Condition<FValue>() {
+              @Override
+              public boolean value(FValue value) {
+                return value.state == FValue.STATE.SELECTED && value.name.equals(setting.getFieldName());
+              }
+            });
+            if (myValue == null) {
+              continue;
+            }
+            if (!groupReported) {
+              if (firstSettingGroupTop) {
+                builder.append("<b>");
+              } else {
+                builder.append("<br><b>").append(entry.getKey().name).append("</b>");
+              }
+            }
+            builder.append("<br>");
+            String postNameSign = setting.getUiName().endsWith(":") ?  " " : ": ";
+            builder.append(setting.getUiName()).append(postNameSign).append(setting.getValueUiName(myValue.value));
+            if (!groupReported) {
+              if (firstSettingGroupTop) {
+                builder.append("</b>");
+              }
+            }
+            groupReported = true;
+          }
+        }
+      }
+    }
+    return builder.toString();
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/ui/FExtractedSettingsDialog.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/ui/FExtractedSettingsDialog.java
new file mode 100644 (file)
index 0000000..659a913
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.extractor.ui;
+
+import com.intellij.application.options.codeStyle.OptionTableWithPreviewPanel;
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.codeStyle.CodeStyleSettingRepresentation;
+import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import com.intellij.psi.codeStyle.extractor.values.FValue;
+import com.intellij.ui.SpeedSearchComparator;
+import com.intellij.ui.TreeTableSpeedSearch;
+import com.intellij.ui.components.JBScrollPane;
+import com.intellij.ui.components.panels.HorizontalLayout;
+import com.intellij.ui.treeStructure.treetable.*;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.AbstractTableCellEditor;
+import com.intellij.util.ui.ColumnInfo;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.tree.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Roman.Shein
+ * @since 28.09.2015.
+ */
+public class FExtractedSettingsDialog extends DialogWrapper {
+  protected FCodeStyleSettingsNameProvider myNameProvider;
+  protected List<FValue> myValues;
+  protected DefaultMutableTreeNode myRoot;
+
+  public FExtractedSettingsDialog(@Nullable Project project, @NotNull FCodeStyleSettingsNameProvider nameProvider, @NotNull List<FValue> values) {
+    super(project, false);
+    myNameProvider = nameProvider;
+    myValues = values;
+    setModal(true);
+    init();
+    setTitle("Extracted Code Style Settings");
+  }
+
+  @Nullable
+  @Override
+  protected JComponent createCenterPanel() {
+    JComponent result = buildExtractedSettingsTree();
+    return result;
+  }
+
+  public boolean valueIsSelectedInTree(@NotNull FValue value) {
+    if (myRoot == null) return false;
+    return valueIsSelectedInTree(myRoot, value);
+  }
+
+  protected boolean valueIsSelectedInTree(@NotNull TreeNode startNode, @NotNull FValue value) {
+    for (Enumeration children = startNode.children(); children.hasMoreElements();) {
+      Object child = children.nextElement();
+      if (child instanceof SettingsTreeNode) {
+        SettingsTreeNode settingsChild = (SettingsTreeNode) child;
+        if (settingsChild.accepted && value.equals(settingsChild.myValue)) {
+          return true;
+        }
+        if (valueIsSelectedInTree(settingsChild, value)) return true;
+      } else if (child instanceof TreeNode) {
+        if (valueIsSelectedInTree((TreeNode) child, value)) return true;
+      }
+    }
+    return false;
+  }
+
+  public static class SettingsTreeNode extends DefaultMutableTreeNode {
+    protected CodeStyleSettingRepresentation myRepresentation;
+    protected boolean accepted = true;
+    protected final String valueString;
+    protected final boolean isGroupNode;
+    protected final String customTitle;
+    protected FValue myValue;
+
+    public SettingsTreeNode(String valueString, CodeStyleSettingRepresentation representation, boolean isGroupNode, FValue value) {
+      this(valueString, representation, isGroupNode, null, value);
+    }
+
+    public SettingsTreeNode(String valueString, CodeStyleSettingRepresentation representation, boolean isGroupNode, String customTitle,
+                            FValue value) {
+      this.valueString = valueString;
+      this.myRepresentation = representation;
+      this.isGroupNode = isGroupNode;
+      this.customTitle = customTitle;
+      this.myValue = value;
+    }
+
+    public SettingsTreeNode(String title) {
+      this(title, null, true, null);
+    }
+
+    public boolean isGroupOrTypeNode() {
+      return isGroupNode;
+    }
+
+    @NotNull
+    public String getTitle() {
+      return customTitle != null ? customTitle : (myRepresentation == null ? valueString : myRepresentation.getUiName());
+    }
+
+    @Nullable
+    public String getValueString() {
+      return myRepresentation == null ? null : valueString;
+    }
+  }
+
+  protected static ColumnInfo getTitleColumnInfo() {
+    return new ColumnInfo("TITLE") {
+      @Nullable
+      @Override
+      public Object valueOf(Object o) {
+        if (o instanceof SettingsTreeNode) {
+          return ((SettingsTreeNode) o).getTitle();
+        } else {
+          return o.toString();
+        }
+      }
+
+      @Override
+      public Class getColumnClass() {
+        return TreeTableModel.class;
+      }
+    };
+  }
+
+  protected static class ValueRenderer implements TableCellRenderer {
+    private final JLabel myLabel = new JLabel();
+    private final JCheckBox myCheckBox = new JCheckBox();
+    private final JPanel myPanel = new JPanel(new HorizontalLayout(0));
+    {
+      myPanel.add(myLabel);
+      myPanel.add(myCheckBox);
+    }
+
+    @NotNull
+    @Override
+    public Component getTableCellRendererComponent(JTable table,
+                                                   Object value,
+                                                   boolean isSelected,
+                                                   boolean hasFocus,
+                                                   int row,
+                                                   int column) {
+      if (table instanceof TreeTable) {
+        table.setEnabled(true);
+        DefaultMutableTreeNode valueNode = (DefaultMutableTreeNode)((TreeTable) table).getTree().getPathForRow(row).getLastPathComponent();
+        if (valueNode instanceof SettingsTreeNode) {
+          SettingsTreeNode settingsNode = (SettingsTreeNode) valueNode;
+          myLabel.setText(settingsNode.getValueString());
+          myCheckBox.setEnabled(true);
+          myCheckBox.setSelected(settingsNode.accepted);
+        } else {
+          myLabel.setBackground(table.getBackground());
+          myCheckBox.setEnabled(false);
+        }
+      }
+      return myPanel;
+    }
+  }
+
+  protected static class ValueEditor extends AbstractTableCellEditor {
+
+    private final JLabel myLabel = new JLabel();
+    private final JCheckBox myCheckBox = new JCheckBox();
+    private final JPanel myPanel = new JPanel(new HorizontalLayout(0));
+    {
+      myPanel.add(myLabel);
+      myPanel.add(myCheckBox);
+    }
+
+    private SettingsTreeNode myCurrentNode;
+    private TreeTable myCurrentTree;
+    final ActionListener itemChoiceListener = new ActionListener() {
+      @Override
+      public void actionPerformed(@NotNull ActionEvent e) {
+        if (myCurrentNode != null) {
+          boolean wasChanged = myCurrentNode.accepted != myCheckBox.isSelected();
+          myCurrentNode.accepted = myCheckBox.isSelected();
+          if (wasChanged) {
+            updateAncestorsUi(myCurrentNode.accepted, myCurrentNode);
+            updateChildrenUi(myCurrentNode);
+          }
+          if (myCurrentTree != null) {
+            myCurrentTree.repaint();
+          }
+        }
+      }
+    };
+
+    protected void updateAncestorsUi(boolean accepted, SettingsTreeNode node) {
+      TreeNode parent = node.getParent();
+      if (parent != null && parent instanceof SettingsTreeNode) {
+        SettingsTreeNode settingsParent = (SettingsTreeNode) parent;
+        settingsParent.accepted = false;
+        if (!accepted) {
+          //propagate disabled settings upwards
+          updateAncestorsUi(false, settingsParent);
+        } else {
+          for (Enumeration children = parent.children(); children.hasMoreElements(); ) {
+            Object child = children.nextElement();
+            if ((child instanceof SettingsTreeNode) && !((SettingsTreeNode) child).accepted) return;
+          }
+          settingsParent.accepted = true;
+          updateAncestorsUi(true, settingsParent);
+        }
+      }
+    }
+
+    protected void updateChildrenUi(SettingsTreeNode node) {
+      for (Enumeration children = node.children(); children.hasMoreElements(); ) {
+        Object child = children.nextElement();
+        if (child instanceof SettingsTreeNode) {
+          SettingsTreeNode settingsChild = (SettingsTreeNode) child;
+          settingsChild.accepted = node.accepted;
+          updateChildrenUi(settingsChild);
+        }
+      }
+    }
+
+    public ValueEditor() {
+      myCheckBox.addActionListener(itemChoiceListener);
+    }
+
+    @Override
+    public Object getCellEditorValue() {
+      return myCheckBox.isSelected();
+    }
+
+    @Override
+    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+      DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) ((TreeTable) table).getTree().getPathForRow(row).getLastPathComponent();
+      if (treeNode instanceof SettingsTreeNode) {
+        myCurrentTree = (TreeTable) table;
+        myCurrentNode = (SettingsTreeNode) treeNode;
+        myLabel.setText(myCurrentNode.getValueString());
+        myCheckBox.setSelected(myCurrentNode.accepted);
+      }
+      return myPanel;
+    }
+  }
+
+  private static ValueRenderer myValueRenderer = new ValueRenderer();
+  private static ValueEditor myValueEditor = new ValueEditor();
+
+  protected static ColumnInfo getValueColumnInfo() {
+    return new ColumnInfo("VALUE") {
+      @Nullable
+      @Override
+      public Object valueOf(Object o) {
+        if (o instanceof SettingsTreeNode) {
+          return ((SettingsTreeNode) o).getValueString();
+        } else {
+          return null;
+        }
+      }
+
+      @Override
+      public TableCellRenderer getRenderer(Object o) {
+        return myValueRenderer;
+      }
+
+      public TableCellEditor getEditor(Object o) {
+        return myValueEditor;
+      }
+
+      @Override
+      public boolean isCellEditable(Object o) {
+        return o instanceof SettingsTreeNode;
+      }
+    };
+  }
+
+  protected JComponent buildExtractedSettingsTree() {
+
+    Collection<FValue> unusedValues = ContainerUtil.newHashSet(myValues);
+    myRoot = new DefaultMutableTreeNode();
+    for (Map.Entry<LanguageCodeStyleSettingsProvider.SettingsType,
+      Map<CodeStyleSettingRepresentation.SettingsGroup, List<CodeStyleSettingRepresentation>>> typeEntry : myNameProvider.mySettings.entrySet()) {
+      DefaultMutableTreeNode settingsNode = null;
+      for (Map.Entry<CodeStyleSettingRepresentation.SettingsGroup, List<CodeStyleSettingRepresentation>> groupEntry: typeEntry.getValue().entrySet()) {
+        CodeStyleSettingRepresentation.SettingsGroup group = groupEntry.getKey();
+        List<CodeStyleSettingRepresentation> representations = groupEntry.getValue();
+        List<CodeStyleSettingRepresentation> children = ContainerUtil.emptyList();
+        DefaultMutableTreeNode groupNode = null;
+        if (group.name == null && !representations.isEmpty()) {
+          //there is a setting with name coinciding with group name
+          if (representations.size() > 1) {
+            children = representations.subList(1, representations.size());
+          }
+          CodeStyleSettingRepresentation headRep = representations.get(0);
+          FValue myValue = FCodeStyleSettingsNameProvider.getValue(headRep, myValues);
+          if (myValue == null) {
+            //value was not found (was not selected)
+            groupNode = new SettingsTreeNode(headRep.getUiName());
+          } else {
+            groupNode = new SettingsTreeNode(headRep.getUiName());
+            groupNode.add(new SettingsTreeNode(headRep.getValueUiName(myValue.value), headRep, true, myValue));
+            unusedValues.remove(myValue);
+          }
+        } else {
+          children = representations;
+        }
+        for (CodeStyleSettingRepresentation representation: children) {
+          FValue myValue = FCodeStyleSettingsNameProvider.getValue(representation, myValues);
+          if (myValue != null) {
+            if (groupNode == null) {
+              groupNode = new SettingsTreeNode(group.name);
+            }
+            groupNode.add(new SettingsTreeNode(representation.getValueUiName(myValue.value), representation, false, myValue));
+            unusedValues.remove(myValue);
+          }
+        }
+        if (groupNode != null) {
+          if (settingsNode == null) {
+            settingsNode = new SettingsTreeNode(FCodeStyleSettingsNameProvider.getSettingsTypeName(typeEntry.getKey()));
+          }
+          settingsNode.add(groupNode);
+        }
+      }
+      if (settingsNode != null) {
+        myRoot.add(settingsNode);
+      }
+    }
+
+    unusedValues = ContainerUtil.filter(unusedValues, new Condition<FValue>(){
+      @Override
+      public boolean value(FValue value) {
+        return value.state == FValue.STATE.SELECTED;
+      }
+    });
+
+    DefaultMutableTreeNode unnamedNode = null;
+    for (FValue value: unusedValues) {
+      if (unnamedNode == null) {
+        unnamedNode = new SettingsTreeNode("Settings without UI representation");
+      }
+      unnamedNode.add(new SettingsTreeNode(value.value.toString(), null, false, value.name, value));
+    }
+
+    if (unnamedNode != null) {
+      myRoot.add(unnamedNode);
+    }
+
+    final ColumnInfo[] COLUMNS = new ColumnInfo[]{getTitleColumnInfo(), getValueColumnInfo()};
+
+    ListTreeTableModel model = new ListTreeTableModel(myRoot, COLUMNS);
+    final TreeTable treeTable = new TreeTable(model) {
+      @Override
+      public TreeTableCellRenderer createTableRenderer(TreeTableModel treeTableModel) {
+        TreeTableCellRenderer tableRenderer = super.createTableRenderer(treeTableModel);
+        UIUtil.setLineStyleAngled(tableRenderer);
+        tableRenderer.setRootVisible(false);
+        tableRenderer.setShowsRootHandles(true);
+
+        return tableRenderer;
+      }
+
+      @Override
+      public TableCellRenderer getCellRenderer(int row, int column) {
+        TreePath treePath = getTree().getPathForRow(row);
+        if (treePath == null) return super.getCellRenderer(row, column);
+
+        Object node = treePath.getLastPathComponent();
+
+        TableCellRenderer renderer = COLUMNS[column].getRenderer(node);
+        return renderer == null ? super.getCellRenderer(row, column) : renderer;
+      }
+
+      @Override
+      public TableCellEditor getCellEditor(int row, int column) {
+        TreePath treePath = getTree().getPathForRow(row);
+        if (treePath == null) return super.getCellEditor(row, column);
+
+        Object node = treePath.getLastPathComponent();
+        TableCellEditor editor = COLUMNS[column].getEditor(node);
+        return editor == null ? super.getCellEditor(row, column) : editor;
+      }
+    };
+    new TreeTableSpeedSearch(treeTable).setComparator(new SpeedSearchComparator(false));
+
+    treeTable.setRootVisible(false);
+
+    final JTree tree = treeTable.getTree();
+    tree.setCellRenderer(myTitleRenderer);
+    tree.setShowsRootHandles(true);
+    treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+    treeTable.setTableHeader(null);
+
+    OptionTableWithPreviewPanel.expandTree(tree);
+
+    treeTable.getColumnModel().getSelectionModel().setAnchorSelectionIndex(1);
+    treeTable.getColumnModel().getSelectionModel().setLeadSelectionIndex(1);
+
+    int maxWidth = tree.getPreferredScrollableViewportSize().width + 10;
+    final TableColumn titleColumn = treeTable.getColumnModel().getColumn(0);
+    titleColumn.setPreferredWidth(maxWidth);
+    titleColumn.setMinWidth(maxWidth);
+    titleColumn.setMaxWidth(maxWidth);
+    titleColumn.setResizable(false);
+
+    final Dimension valueSize = new JLabel(ApplicationBundle.message("option.table.sizing.text")).getPreferredSize();
+    treeTable.setPreferredScrollableViewportSize(new Dimension(maxWidth + valueSize.width + 10, 20));
+    treeTable.setBackground(UIUtil.getPanelBackground());
+    treeTable.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
+
+    final Dimension screenSize = treeTable.getToolkit().getScreenSize();
+    JBScrollPane scroller = new JBScrollPane(treeTable) {
+      @Override
+      public Dimension getMinimumSize() {
+        return super.getPreferredSize();
+      }
+    };
+    final Dimension preferredSize = new Dimension(Math.min(screenSize.width / 2, treeTable.getPreferredSize().width),
+                                                  Math.min(screenSize.height / 2, treeTable.getPreferredSize().height));
+    getRootPane().setPreferredSize(preferredSize);
+    return scroller;
+  }
+
+  final TreeCellRenderer myTitleRenderer = new CellRenderer();
+
+  public static class CellRenderer implements TreeCellRenderer {
+
+    private final JLabel myLabel = new JLabel();
+
+    @NotNull
+    @Override
+    public Component getTreeCellRendererComponent(JTree tree,
+                                                  Object value,
+                                                  boolean selected,
+                                                  boolean expanded,
+                                                  boolean leaf,
+                                                  int row,
+                                                  boolean hasFocus) {
+      if (value instanceof SettingsTreeNode) {
+        SettingsTreeNode node = (SettingsTreeNode) value;
+        myLabel.setText(node.getTitle());
+        myLabel.setFont(node.isGroupOrTypeNode() ? myLabel.getFont().deriveFont(Font.BOLD) : myLabel.getFont().deriveFont(Font.PLAIN));
+      } else {
+        myLabel.setText(value.toString());
+        myLabel.setFont(myLabel.getFont().deriveFont(Font.BOLD));
+      }
+
+      Color foreground = selected ? UIUtil.getTableSelectionForeground() : UIUtil.getTableForeground();
+      myLabel.setForeground(foreground);
+
+      return myLabel;
+    }
+  }
+}
index ac334ab32112f2a0941c5b161479fd7d54d844aa..59449a204b4d49904661a97ca692fe2655a02cf9 100644 (file)
     <extensionPoint name="lang.rearranger" beanClass="com.intellij.lang.LanguageExtensionPoint">
       <with attribute="implementationClass" implements="com.intellij.psi.codeStyle.arrangement.Rearranger"/>
     </extensionPoint>
+    <extensionPoint name="lang.formatting.extractor" beanClass="com.intellij.lang.LanguageExtensionPoint">
+      <with attribute="implementationClass" implements="com.intellij.psi.codeStyle.extractor.differ.FLangCodeStyleExtractor"/>
+    </extensionPoint>
     <extensionPoint name="rearranger.ui" interface="com.intellij.psi.codeStyle.arrangement.std.ArrangementUiComponent$Factory"/>
 
     <extensionPoint name="lang.surroundDescriptor" beanClass="com.intellij.lang.LanguageExtensionPoint">
index 4c068d1be0403cbd3d4bd1ef49fa15b842fbe55d..2317ddef3c5c2e2c9ce5ff57909d06c09ac1726e 100644 (file)
         <action id="AutoIndentLines" class="com.intellij.codeInsight.generation.actions.AutoIndentLinesAction"/>
         <action id="OptimizeImports" class="com.intellij.codeInsight.actions.OptimizeImportsAction"/>
         <action id="RearrangeCode" class="com.intellij.application.options.codeStyle.arrangement.action.RearrangeCodeAction"/>
+        <action id="ExtractCodeStyle"
+                class="com.intellij.psi.codeStyle.extractor.FExtractCodeStyleAction"
+                text="Extract code style"
+                description="Extract code style settings from current file"/>
       </group>
 
       <separator/>
index f56ab058f8428942b25742eaed57c9c90ee86b69..ac2e1600931cd7862102d6da16ad4849a63b9f42 100644 (file)
     <lang.whiteSpaceFormattingStrategy language="JAVA"
                                        implementationClass="com.intellij.psi.formatter.JavadocWhiteSpaceFormattingStrategy"/>
     <lang.rearranger language="JAVA" implementationClass="com.intellij.psi.codeStyle.arrangement.JavaRearranger"/>
+    <lang.formatting.extractor language="JAVA" implementationClass="com.intellij.psi.codeStyle.extractor.differ.FJavaExtractor"/>
 
     <lang.documentationProvider language="JAVA" implementationClass="com.intellij.lang.java.JavaDocumentationProvider"/>
     <documentationProvider implementation="com.intellij.lang.java.FileDocumentationProvider" order="last"/>