diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java index 233825ad6688..35ce6e890f52 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java @@ -173,8 +173,9 @@ public class AnnotationsHighlightUtil { Set names = new HashSet(); PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); for (PsiNameValuePair attribute : attributes) { - if (attribute.getName() != null) { - names.add(attribute.getName()); + final String name = attribute.getName(); + if (name != null) { + names.add(name); } else { names.add(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME); @@ -211,8 +212,9 @@ public class AnnotationsHighlightUtil { @Nullable public static HighlightInfo checkConstantExpression(PsiExpression expression) { - if (expression.getParent() instanceof PsiAnnotationMethod || expression.getParent() instanceof PsiNameValuePair) { - if (PsiType.NULL.equals(expression.getType()) || !PsiUtil.isConstantExpression(expression)) { + final PsiElement parent = expression.getParent(); + if (parent instanceof PsiAnnotationMethod || parent instanceof PsiNameValuePair || parent instanceof PsiArrayInitializerMemberValue) { + if (!PsiUtil.isConstantExpression(expression)) { return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, JavaErrorMessages.message("annotation.nonconstant.attribute.value")); } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java index 06f5fc16c561..56939ccced68 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java @@ -415,11 +415,14 @@ public class ClassElement extends CompositeElement implements Constants { else { // The main idea is to avoid to anchor to 'white space' element because that causes reformatting algorithm // to perform incorrectly. The algorithm is encapsulated at PostprocessReformattingAspect.doPostponedFormattingInner(). - PsiElement result = aClass.getLBrace().getNextSibling(); - while (result instanceof PsiWhiteSpace) { - result = result.getNextSibling(); + final PsiElement lBrace = aClass.getLBrace(); + if (lBrace != null) { + PsiElement result = lBrace.getNextSibling(); + while (result instanceof PsiWhiteSpace) { + result = result.getNextSibling(); + } + return result; } - return result; } } lastMember = child; diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java index 0d5ccb973e92..da8472d0ddbd 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java @@ -230,7 +230,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { final PsiFile containingFile = element.getContainingFile(); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); for (RangeMarker occurrenceMarker : myOccurrenceMarkers) { - restoreExpression(containingFile, (PsiVariable)vars[0], elementFactory, occurrenceMarker, myExpressionText); + if (restoreExpression(containingFile, (PsiVariable)vars[0], elementFactory, occurrenceMarker, myExpressionText) == null) return; } element.delete(); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/nonConstantInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/nonConstantInitializer.java index 82a151b61755..c8998b249f25 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/nonConstantInitializer.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/nonConstantInitializer.java @@ -1,10 +1,14 @@ @interface Ann { int i (); + + String[] j(); } class D { int field; @Ann(i=field) void foo () {} + + @Ann(j={null}) void bar() {} } @interface ManistaDouble diff --git a/platform/lang-api/src/com/intellij/find/FindModel.java b/platform/lang-api/src/com/intellij/find/FindModel.java index 5f4cbc12dd68..616e1b2211dc 100644 --- a/platform/lang-api/src/com/intellij/find/FindModel.java +++ b/platform/lang-api/src/com/intellij/find/FindModel.java @@ -98,7 +98,11 @@ public class FindModel extends UserDataHolderBase implements Cloneable { * @param preserveCase the value of the Preserve Case flag. */ public void setPreserveCase(boolean preserveCase) { + boolean changed = isPreserveCase != preserveCase; isPreserveCase = preserveCase; + if (changed) { + notifyObservers(); + } } private boolean isPreserveCase = false; diff --git a/platform/lang-api/src/com/intellij/formatting/FormattingDocumentModel.java b/platform/lang-api/src/com/intellij/formatting/FormattingDocumentModel.java index 7a054200fbdc..8e75e780760b 100644 --- a/platform/lang-api/src/com/intellij/formatting/FormattingDocumentModel.java +++ b/platform/lang-api/src/com/intellij/formatting/FormattingDocumentModel.java @@ -67,7 +67,7 @@ public interface FormattingDocumentModel { boolean containsWhiteSpaceSymbolsOnly(int startOffset, int endOffset); /** - * There is a possible case that white space to apply because of formatter processing should be additionally adjusted. That is + * There is a possible case that white space to apply should be additionally adjusted because of formatter processing. That is * true, for example, for Python where it may be mandatory to use '\' symbol at multi-line expression. *

* Current method adjusts given white space text if necessary. @@ -75,10 +75,12 @@ public interface FormattingDocumentModel { * @param whiteSpaceText white space text to use by default * @param startOffset start offset of the document text that is intended to be replaced by the given white space text (inclusive) * @param endOffset end offset of the document text that is intended to be replaced by the given white space text (exclusive) + * @param changedViaPsi flag that identifies whether formatter introduces changes via PSI tree or directly via the document * @return white space to use for replacing document symbols at [startOffset; endOffset) region */ @NotNull - CharSequence adjustWhiteSpaceIfNecessary(@NotNull CharSequence whiteSpaceText, int startOffset, int endOffset); + CharSequence adjustWhiteSpaceIfNecessary(@NotNull CharSequence whiteSpaceText, int startOffset, int endOffset, + boolean changedViaPsi); ///** // * Allows to answer if given symbol is treated by the current model as white space symbol during formatting. diff --git a/platform/lang-api/src/com/intellij/formatting/WhiteSpaceFormattingStrategy.java b/platform/lang-api/src/com/intellij/formatting/WhiteSpaceFormattingStrategy.java index 3d5725204520..7248f3bd6497 100644 --- a/platform/lang-api/src/com/intellij/formatting/WhiteSpaceFormattingStrategy.java +++ b/platform/lang-api/src/com/intellij/formatting/WhiteSpaceFormattingStrategy.java @@ -15,6 +15,7 @@ */ package com.intellij.formatting; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; /** @@ -65,5 +66,24 @@ public interface WhiteSpaceFormattingStrategy { * @return symbols to use for replacing [startOffset; endOffset) sub-sequence of the given text */ @NotNull - CharSequence adjustWhiteSpaceIfNecessary(@NotNull CharSequence whiteSpaceText, @NotNull CharSequence text, int startOffset, int endOffset); + CharSequence adjustWhiteSpaceIfNecessary(@NotNull CharSequence whiteSpaceText, @NotNull CharSequence text, int startOffset, + int endOffset); + + + /** + * PSI-based version of {@link #adjustWhiteSpaceIfNecessary(CharSequence, CharSequence, int, int)}. + *

+ * There is a possible case that particular changes are performed to PSI tree and it's not yet synchronized with the underlying + * document. Hence, we can't directly work with document char sequence but need to traverse PSI tree instead. I.e. we start with + * particular PSI element that contains given start offset and process its right siblings/relatives until given end offset + * is reached. + * + * @param whiteSpaceText white space text to use by default for replacing sub-sequence of the given text + * @param startElement PSI element that contains given start offset + * @param startOffset start offset to use with the given text (inclusive) + * @param endOffset end offset to use with the given text (exclusive) + * @return symbols to use for replacing [startOffset; endOffset) sub-sequence of the given text + */ + CharSequence adjustWhiteSpaceIfNecessary(@NotNull CharSequence whiteSpaceText, @NotNull PsiElement startElement, int startOffset, + int endOffset); } diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java index e5daad1340c0..2a608531a170 100644 --- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java +++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java @@ -80,6 +80,10 @@ public class WizardContext { "Projects"; } + public boolean isProjectFileDirectorySet() { + return myProjectFileDirectory != null; + } + public void setProjectFileDirectory(String projectFileDirectory) { myProjectFileDirectory = projectFileDirectory; } 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 d0138253edfa..9f16a2ab6e12 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java @@ -16,8 +16,11 @@ package com.intellij.psi.codeStyle; import com.intellij.openapi.application.ApplicationBundle; +import org.jetbrains.annotations.Nullable; public interface CodeStyleSettingsCustomizable { + enum OptionAnchor {NONE, BEFORE, AFTER} + String SPACES_AROUND_OPERATORS = ApplicationBundle.message("group.spaces.around.operators"); String SPACES_BEFORE_PARENTHESES = ApplicationBundle.message("group.spaces.before.parentheses"); String SPACES_BEFORE_LEFT_BRACE = ApplicationBundle.message("group.spaces.before.left.brace"); @@ -107,7 +110,15 @@ public interface CodeStyleSettingsCustomizable { void showCustomOption(Class settingsClass, String fieldName, String title, - String groupName, + @Nullable String groupName, + Object... options); + + void showCustomOption(Class settingsClass, + String fieldName, + String title, + @Nullable String groupName, + @Nullable OptionAnchor anchor, + @Nullable String anchorFieldName, Object... options); void renameStandardOption(String fieldName, String newTitle); diff --git a/platform/lang-api/src/com/intellij/psi/formatter/AbstractWhiteSpaceFormattingStrategy.java b/platform/lang-api/src/com/intellij/psi/formatter/AbstractWhiteSpaceFormattingStrategy.java index d9ff716877bd..0e3e40cc15e6 100644 --- a/platform/lang-api/src/com/intellij/psi/formatter/AbstractWhiteSpaceFormattingStrategy.java +++ b/platform/lang-api/src/com/intellij/psi/formatter/AbstractWhiteSpaceFormattingStrategy.java @@ -16,7 +16,11 @@ package com.intellij.psi.formatter; import com.intellij.formatting.WhiteSpaceFormattingStrategy; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Abstract common {@link WhiteSpaceFormattingStrategy} implementation that doesn't replace default strategy and doesn't @@ -42,4 +46,54 @@ public abstract class AbstractWhiteSpaceFormattingStrategy implements WhiteSpace // Does nothing return whiteSpaceText; } + + @Override + public CharSequence adjustWhiteSpaceIfNecessary(@NotNull CharSequence whiteSpaceText, + @NotNull PsiElement startElement, + final int startOffset, + final int endOffset) + { + assert startElement.getTextRange().contains(startOffset) + : String.format("Element: %s, range: %s, offset: %d", startElement, startElement.getTextRange(), startOffset); + + // Collect target text from the PSI elements and delegate to the text-based method. + StringBuilder buffer = new StringBuilder(); + for (PsiElement current = startElement; current != null && current.getTextRange().getStartOffset() < endOffset; current = next(current)) { + final TextRange range = current.getTextRange(); + final String text = current.getText(); + if (StringUtil.isEmpty(text)) { + continue; + } + + int start = startOffset > range.getStartOffset() ? startOffset - range.getStartOffset() : 0; + if (start >= text.length()) { + continue; + } + + int end = endOffset < range.getEndOffset() ? text.length() - (range.getEndOffset() - endOffset) : text.length(); + if (end <= start) { + continue; + } + + if (start == 0 && end == text.length()) { + buffer.append(text); + } + else { + buffer.append(text.substring(start, end)); + } + } + + return adjustWhiteSpaceIfNecessary(whiteSpaceText, buffer, 0, endOffset - startOffset); + } + + @Nullable + private static PsiElement next(final @NotNull PsiElement element) { + for (PsiElement anchor = element; anchor != null; anchor = anchor.getParent()) { + final PsiElement result = element.getNextSibling(); + if (result != null) { + return result; + } + } + return null; + } } diff --git a/platform/lang-api/src/com/intellij/psi/formatter/CompositeWhiteSpaceFormattingStrategy.java b/platform/lang-api/src/com/intellij/psi/formatter/CompositeWhiteSpaceFormattingStrategy.java index 015058b1497a..8646e336641c 100644 --- a/platform/lang-api/src/com/intellij/psi/formatter/CompositeWhiteSpaceFormattingStrategy.java +++ b/platform/lang-api/src/com/intellij/psi/formatter/CompositeWhiteSpaceFormattingStrategy.java @@ -16,6 +16,7 @@ package com.intellij.psi.formatter; import com.intellij.formatting.WhiteSpaceFormattingStrategy; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -86,4 +87,17 @@ public class CompositeWhiteSpaceFormattingStrategy implements WhiteSpaceFormatti } return result; } + + @Override + public CharSequence adjustWhiteSpaceIfNecessary(@NotNull CharSequence whiteSpaceText, + @NotNull PsiElement startElement, + int startOffset, + int endOffset) + { + CharSequence result = whiteSpaceText; + for (WhiteSpaceFormattingStrategy strategy : myStrategies) { + result = strategy.adjustWhiteSpaceIfNecessary(result, startElement, startOffset, endOffset); + } + return result; + } } diff --git a/platform/lang-api/src/com/intellij/util/FileContentUtil.java b/platform/lang-api/src/com/intellij/util/FileContentUtil.java index d627f9c15300..4a29dce33a44 100644 --- a/platform/lang-api/src/com/intellij/util/FileContentUtil.java +++ b/platform/lang-api/src/com/intellij/util/FileContentUtil.java @@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -37,6 +38,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Set; /** @@ -102,4 +104,10 @@ public class FileContentUtil { } events.add(new VFilePropertyChangeEvent(FORCE_RELOAD_REQUESTOR, virtualFile, VirtualFile.PROP_NAME, virtualFile.getName(), virtualFile.getName(), false)); } + + public static void reparseOpenedFiles() { + for (Project project : ProjectManager.getInstance().getOpenProjects()) { + reparseFiles(project, Collections.emptyList(), true); + } + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleBlankLinesPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleBlankLinesPanel.java index a7c0f9e930d4..e2227c87ba00 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleBlankLinesPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleBlankLinesPanel.java @@ -27,6 +27,7 @@ import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider; import com.intellij.ui.OptionGroup; import com.intellij.util.containers.MultiMap; import gnu.trove.THashMap; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -185,10 +186,21 @@ public class CodeStyleBlankLinesPanel extends MultilanguageCodeStyleAbstractPane } } + @Override public void showCustomOption(Class settingsClass, String fieldName, String title, String groupName, Object... options) { + showCustomOption(settingsClass, fieldName, title, groupName, null, null, options); + } + + public void showCustomOption(Class settingsClass, + String fieldName, + String title, + String groupName, + @Nullable OptionAnchor anchor, + @Nullable String anchorFieldName, + Object... options) { if (myIsFirstUpdate) { myCustomOptions.putValue(groupName, (Trinity)Trinity.create(settingsClass, fieldName, title)); } 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 0a1a7a84a64a..c334789c2ff7 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 @@ -35,7 +35,11 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable; import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider; import com.intellij.ui.IdeBorderFactory; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,6 +49,10 @@ import javax.swing.event.AncestorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; /** * Base class for code style settings panels supporting multiple programming languages. @@ -63,15 +71,15 @@ public abstract class MultilanguageCodeStyleAbstractPanel extends CodeStyleAbstr } protected void init() { - for(LanguageCodeStyleSettingsProvider provider: Extensions.getExtensions(LanguageCodeStyleSettingsProvider.EP_NAME)) { + for (LanguageCodeStyleSettingsProvider provider : Extensions.getExtensions(LanguageCodeStyleSettingsProvider.EP_NAME)) { provider.customizeSettings(this, getSettingsType()); } } - public boolean setPanelLanguage(Language language) { + public boolean setPanelLanguage(Language language) { boolean languageProviderFound = false; - for(LanguageCodeStyleSettingsProvider provider: Extensions.getExtensions(LanguageCodeStyleSettingsProvider.EP_NAME)) { + for (LanguageCodeStyleSettingsProvider provider : Extensions.getExtensions(LanguageCodeStyleSettingsProvider.EP_NAME)) { if (provider.getLanguage().is(language)) { provider.customizeSettings(this, getSettingsType()); languageProviderFound = true; @@ -79,7 +87,7 @@ public abstract class MultilanguageCodeStyleAbstractPanel extends CodeStyleAbstr } } if (!languageProviderFound) return false; - + myLanguage = language; setSkipPreviewHighlighting(true); @@ -162,21 +170,21 @@ public abstract class MultilanguageCodeStyleAbstractPanel extends CodeStyleAbstr final PsiDocumentManager manager = PsiDocumentManager.getInstance(project); final Document doc = manager.getDocument(psiFile); CommandProcessor.getInstance().executeCommand(project, new Runnable() { - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - doc.replaceString(0, doc.getTextLength(), text); - manager.commitDocument(doc); - try { - CodeStyleManager.getInstance(project).reformat(psiFile); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - }); - } - }, "", ""); + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + doc.replaceString(0, doc.getTextLength(), text); + manager.commitDocument(doc); + try { + CodeStyleManager.getInstance(project).reformat(psiFile); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }); + } + }, "", ""); if (doc != null) { manager.commitDocument(doc); } @@ -237,7 +245,7 @@ public abstract class MultilanguageCodeStyleAbstractPanel extends CodeStyleAbstr } private void selectCurrentLanguageTab() { - for(int i = 0; i < tabbedPane.getTabCount(); i ++) { + for (int i = 0; i < tabbedPane.getTabCount(); i++) { if (getTabName(myLanguage).equals(tabbedPane.getTitleAt(i))) { tabbedPane.setSelectedIndex(i); return; @@ -272,4 +280,71 @@ public abstract class MultilanguageCodeStyleAbstractPanel extends CodeStyleAbstr public Language getDefaultLanguage() { return getSelectedLanguage(); } + + protected List sortOptions(Collection options) { + Set names = new THashSet(ContainerUtil.map(options, new Function() { + @Override + public String fun(OrderedOption option) { + return option.getOptionName(); + } + })); + + List order = new ArrayList(options.size()); + MultiMap afters = new MultiMap(); + MultiMap befores = new MultiMap(); + + for (T each : options) { + String anchorOptionName = each.getAnchorOptionName(); + if (anchorOptionName != null && names.contains(anchorOptionName)) { + if (each.getAnchor() == OptionAnchor.AFTER) { + afters.putValue(anchorOptionName, each); + continue; + } + else if (each.getAnchor() == OptionAnchor.BEFORE) { + befores.putValue(anchorOptionName, each); + continue; + } + } + order.add(each); + } + + List result = new ArrayList(options.size()); + for (T each : order) { + result.addAll(befores.get(each.getOptionName())); + result.add(each); + result.addAll(afters.get(each.getOptionName())); + } + + assert result.size() == options.size(); + return result; + } + + protected abstract static class OrderedOption { + @NotNull private final String optionName; + @Nullable private final OptionAnchor anchor; + @Nullable private final String anchorOptionName; + + protected OrderedOption(@NotNull String optionName, + OptionAnchor anchor, + String anchorOptionName) { + this.optionName = optionName; + this.anchor = anchor; + this.anchorOptionName = anchorOptionName; + } + + @NotNull + public String getOptionName() { + return optionName; + } + + @Nullable + public OptionAnchor getAnchor() { + return anchor; + } + + @Nullable + public String getAnchorOptionName() { + return anchorOptionName; + } + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java index c4be46101146..74bf7b190f71 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java @@ -125,19 +125,31 @@ public abstract class OptionTableWithPreviewPanel extends MultilanguageCodeStyle } } + @Override + public void showCustomOption(Class settingsClass, + String fieldName, + String title, + String groupName, Object... options) { + showCustomOption(settingsClass, fieldName, title, groupName, null, null, options); + } + + @Override public void showCustomOption(Class settingsClass, String fieldName, String title, String groupName, + @Nullable OptionAnchor anchor, + @Nullable String anchorFieldName, Object... options) { if (isFirstUpdate) { Option option; if (options.length == 2) { - option = new SelectionOption(settingsClass, fieldName, title, groupName, (String[])options[0], (int[])options[1]); + option = + new SelectionOption(settingsClass, fieldName, title, groupName, anchor, anchorFieldName, (String[])options[0], (int[])options[1]); } else { - option = new BooleanOption(settingsClass, fieldName, title, groupName); + option = new BooleanOption(settingsClass, fieldName, title, groupName, anchor, anchorFieldName); } myCustomOptions.add(option); option.setEnabled(true); @@ -162,7 +174,8 @@ public abstract class OptionTableWithPreviewPanel extends MultilanguageCodeStyle DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(); Map groupsMap = new THashMap(); - for (Option each : ContainerUtil.concat(myOptions, myCustomOptions)) { + List