diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java
index 427040b6bc3f..56fafd0ad4fa 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java
@@ -296,4 +296,11 @@ public interface CodeStyleSettingsCustomizable {
Object... options);
void renameStandardOption(String fieldName, String newTitle);
+
+ /**
+ * Moves a standard option to another group.
+ * @param fieldName The field name of the option to move (as defined in CommonCodeStyleSettings class).
+ * @param newGroup The new group name (the group may be one of existing ones). A custom group name can be used if supported by consumer.
+ */
+ void moveStandardOption(String fieldName, String newGroup);
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java
index 2721444ee914..71d1ddc3ac4c 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java
@@ -289,6 +289,11 @@ public abstract class LanguageCodeStyleSettingsProvider {
// Ignore
}
+ @Override
+ public void moveStandardOption(String fieldName, String newGroup) {
+ // Ignore
+ }
+
public Set getCollectedFields() {
return myCollectedFields;
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/MultilanguageCodeStyleAbstractPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/MultilanguageCodeStyleAbstractPanel.java
index 88a23eea3428..7e456d33efc8 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/MultilanguageCodeStyleAbstractPanel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/MultilanguageCodeStyleAbstractPanel.java
@@ -287,6 +287,11 @@ public abstract class MultilanguageCodeStyleAbstractPanel extends CodeStyleAbstr
return getSelectedLanguage();
}
+ @Override
+ public void moveStandardOption(String fieldName, String newGroup) {
+ throw new UnsupportedOperationException();
+ }
+
protected List sortOptions(Collection options) {
Set names = new THashSet(ContainerUtil.map(options, new Function() {
@Override
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java
index baf8ac7547f6..99defdf20b8f 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java
@@ -57,6 +57,7 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
private MultiMap myCustomOptions = new MultiMap();
private boolean isFirstUpdate = true;
private final Map myRenamedFields = new THashMap();
+ private final Map myRemappedGroups = new THashMap();
public OptionTreeWithPreviewPanel(CodeStyleSettings settings) {
@@ -180,7 +181,7 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
String groupName = "";
DefaultMutableTreeNode groupNode = null;
- List result = sortOptions(myKeys);
+ List result = sortOptions(orderByGroup(myKeys));
for (BooleanOptionKey key : result) {
String newGroupName = key.groupName;
@@ -235,6 +236,39 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
return optionsTree;
}
+ private List orderByGroup(final List options) {
+ final List groupOrder = getGroupOrder(options);
+ List result = new ArrayList(options.size());
+ result.addAll(options);
+ Collections.sort(result, new Comparator(){
+ @Override
+ public int compare(BooleanOptionKey key1, BooleanOptionKey key2) {
+ String group1 = key1.groupName;
+ String group2 = key2.groupName;
+ if (group1 == null) {
+ return group2 == null ? 0 : 1;
+ }
+ if (group2 == null) {
+ return -1;
+ }
+ Integer index1 = groupOrder.indexOf(group1);
+ Integer index2 = groupOrder.indexOf(group2);
+ if (index1 == -1 || index2 == -1) return group1.compareToIgnoreCase(group2);
+ return index1.compareTo(index2);
+ }
+ });
+ return result;
+ }
+
+ protected List getGroupOrder(List options) {
+ List groupOrder = new ArrayList();
+ for (BooleanOptionKey each : options) {
+ if (each.groupName != null && !groupOrder.contains(each.groupName)) {
+ groupOrder.add(each.groupName);
+ }
+ }
+ return groupOrder;
+ }
private void selectCheckbox(TreePath treePath) {
if (treePath == null) {
@@ -358,9 +392,10 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
try {
Class styleSettingsClass = CodeStyleSettings.class;
Field field = styleSettingsClass.getField(fieldName);
+ String actualGroupName = getRemappedGroup(fieldName, groupName);
BooleanOptionKey key = new BooleanOptionKey(fieldName,
- getRenamedTitle(groupName, groupName),
+ getRenamedTitle(actualGroupName, actualGroupName),
getRenamedTitle(fieldName, title), field);
myKeys.add(key);
}
@@ -622,4 +657,13 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
}
return false;
}
+
+ @Override
+ public void moveStandardOption(String fieldName, String newGroup) {
+ myRemappedGroups.put(fieldName, newGroup);
+ }
+
+ private String getRemappedGroup(String fieldName, String defaultName) {
+ return myRemappedGroups.containsKey(fieldName) ? myRemappedGroups.get(fieldName) : defaultName;
+ }
}