From c02bf6506fffe5929025661a307719365c13009f Mon Sep 17 00:00:00 2001 From: "Svetlana.Zemlyanskay" Date: Mon, 6 Oct 2014 17:26:47 +0400 Subject: [PATCH] IDEA-95126 Arrangement: Provide ability to negate conditions --- .../arrangement/ArrangementUtil.java | 6 +- .../ByModifierArrangementEntryMatcher.java | 17 ++++-- .../match/ByTypeArrangementEntryMatcher.java | 19 ++++-- ...aultArrangementEntryMatcherSerializer.java | 23 ++++++- .../match/StdArrangementEntryMatcher.java | 25 ++++---- .../match/StdArrangementMatchRule.java | 24 +++++--- .../model/ArrangementAtomMatchCondition.java | 23 ++----- .../ArrangementStandardSettingsManager.java | 15 +++-- .../std/ArrangementUiComponent.java | 17 +++++- .../InvertibleArrangementSettingsToken.java | 33 ++++++++++ .../std/StdArrangementSettingsToken.java | 6 +- .../arrangement/std/StdArrangementTokens.java | 59 ++++++++++-------- ...StdInvertibleArrangementSettingsToken.java | 44 ++++++++++++++ .../AbstractArrangementUiComponent.java | 5 ++ ...ArrangementAndMatchConditionComponent.java | 16 ++++- ...rrangementAtomMatchConditionComponent.java | 60 +++++++++++++++++-- .../ArrangementCheckBoxUiComponent.java | 7 ++- .../ArrangementComboBoxUiComponent.java | 5 ++ .../ArrangementLabelUiComponent.java | 5 ++ .../ArrangementTextFieldUiComponent.java | 9 ++- .../match/ArrangementMatchingRuleEditor.java | 6 +- .../util/ArrangementListRowDecorator.java | 10 ++++ .../arrangement/AbstractRearrangerTest.java | 4 ++ 23 files changed, 338 insertions(+), 100 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/InvertibleArrangementSettingsToken.java create mode 100644 platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdInvertibleArrangementSettingsToken.java diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java index 2bc92f71fe94..174db45b2f11 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementUtil.java @@ -205,7 +205,7 @@ public class ArrangementUtil { public void visit(@NotNull ArrangementAtomMatchCondition condition) { ArrangementSettingsToken type = condition.getType(); Object value = condition.getValue(); - result.put(condition.getType(), type.equals(value) ? null : value); + result.put(condition.getType(), type.equals(value) ? null : value); } @Override @@ -260,10 +260,10 @@ public class ArrangementUtil { @Nullable public static ArrangementEntryMatcher buildMatcher(@NotNull ArrangementAtomMatchCondition condition) { if (StdArrangementTokenType.ENTRY_TYPE.is(condition.getType())) { - return new ByTypeArrangementEntryMatcher(condition.getType()); + return new ByTypeArrangementEntryMatcher(condition); } else if (StdArrangementTokenType.MODIFIER.is(condition.getType())) { - return new ByModifierArrangementEntryMatcher(condition.getType()); + return new ByModifierArrangementEntryMatcher(condition); } else if (StdArrangementTokens.Regexp.NAME.equals(condition.getType())) { return new ByNameArrangementEntryMatcher(condition.getValue().toString()); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByModifierArrangementEntryMatcher.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByModifierArrangementEntryMatcher.java index d972eb824fb1..ec58bffb9003 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByModifierArrangementEntryMatcher.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByModifierArrangementEntryMatcher.java @@ -17,6 +17,7 @@ package com.intellij.psi.codeStyle.arrangement.match; import com.intellij.psi.codeStyle.arrangement.ArrangementEntry; import com.intellij.psi.codeStyle.arrangement.ModifierAwareArrangementEntry; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; @@ -30,20 +31,28 @@ import java.util.Set; */ public class ByModifierArrangementEntryMatcher implements ArrangementEntryMatcher { - @NotNull private final Set myModifiers = ContainerUtilRt.newHashSet(); + @NotNull private final Set myModifiers = ContainerUtilRt.newHashSet(); - public ByModifierArrangementEntryMatcher(@NotNull ArrangementSettingsToken interestedModifier) { + public ByModifierArrangementEntryMatcher(@NotNull ArrangementAtomMatchCondition interestedModifier) { myModifiers.add(interestedModifier); } - public ByModifierArrangementEntryMatcher(@NotNull Collection interestedModifiers) { + public ByModifierArrangementEntryMatcher(@NotNull Collection interestedModifiers) { myModifiers.addAll(interestedModifiers); } @Override public boolean isMatched(@NotNull ArrangementEntry entry) { if (entry instanceof ModifierAwareArrangementEntry) { - return ((ModifierAwareArrangementEntry)entry).getModifiers().containsAll(myModifiers); + final Set modifiers = ((ModifierAwareArrangementEntry)entry).getModifiers(); + for (ArrangementAtomMatchCondition condition : myModifiers) { + final Object value = condition.getValue(); + boolean isInverted = value instanceof Boolean && !((Boolean)value); + if (isInverted == modifiers.contains(condition.getType())) { + return false; + } + } + return true; } return false; } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByTypeArrangementEntryMatcher.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByTypeArrangementEntryMatcher.java index 14a429fbc80a..b994490fb60a 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByTypeArrangementEntryMatcher.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByTypeArrangementEntryMatcher.java @@ -17,6 +17,7 @@ package com.intellij.psi.codeStyle.arrangement.match; import com.intellij.psi.codeStyle.arrangement.ArrangementEntry; import com.intellij.psi.codeStyle.arrangement.TypeAwareArrangementEntry; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; @@ -36,26 +37,34 @@ import java.util.Set; */ public class ByTypeArrangementEntryMatcher implements ArrangementEntryMatcher { - @NotNull private final Set myTypes = ContainerUtilRt.newHashSet(); + @NotNull private final Set myTypes = ContainerUtilRt.newHashSet(); - public ByTypeArrangementEntryMatcher(@NotNull ArrangementSettingsToken interestedType) { + public ByTypeArrangementEntryMatcher(@NotNull ArrangementAtomMatchCondition interestedType) { myTypes.add(interestedType); } - public ByTypeArrangementEntryMatcher(@NotNull Collection interestedTypes) { + public ByTypeArrangementEntryMatcher(@NotNull Collection interestedTypes) { myTypes.addAll(interestedTypes); } @Override public boolean isMatched(@NotNull ArrangementEntry entry) { if (entry instanceof TypeAwareArrangementEntry) { - return ((TypeAwareArrangementEntry)entry).getTypes().containsAll(myTypes); + final Set types = ((TypeAwareArrangementEntry)entry).getTypes(); + for (ArrangementAtomMatchCondition condition : myTypes) { + final Object value = condition.getValue(); + boolean isInverted = value instanceof Boolean && !((Boolean)value); + if (isInverted == types.contains(condition.getType())) { + return false; + } + } + return true; } return false; } @NotNull - public Set getTypes() { + public Set getTypes() { return myTypes; } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementEntryMatcherSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementEntryMatcherSerializer.java index b99f2aa45057..2584ec148ef1 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementEntryMatcherSerializer.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementEntryMatcherSerializer.java @@ -150,12 +150,30 @@ public class DefaultArrangementEntryMatcherSerializer { if (text != null && processInnerText) { text = StringUtil.unescapeStringCharacters(matcherElement.getText()); if (!StringUtil.isEmpty(text)) { - value = text; + final Boolean booleanValue = parseBooleanValue(text); + if (booleanValue != null) { + value = booleanValue; + } + else { + value = text; + } } } return new ArrangementAtomMatchCondition(token, value); } + @Nullable + private static Boolean parseBooleanValue(@NotNull String text) { + if (StringUtil.equalsIgnoreCase(text, Boolean.TRUE.toString())) { + return true; + } + + if (StringUtil.equalsIgnoreCase(text, Boolean.FALSE.toString())) { + return false; + } + return null; + } + private static class MySerializationVisitor implements ArrangementMatchConditionVisitor { Element result; @@ -168,6 +186,9 @@ public class DefaultArrangementEntryMatcherSerializer { if (StdArrangementTokenType.REG_EXP.is(type)) { element.setText(StringUtil.escapeStringCharacters(condition.getValue().toString())); } + else if (condition.getValue() instanceof Boolean) { + element.setText(condition.getValue().toString()); + } register(element); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementEntryMatcher.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementEntryMatcher.java index 3225405b94cb..9d4819677803 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementEntryMatcher.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementEntryMatcher.java @@ -18,10 +18,7 @@ package com.intellij.psi.codeStyle.arrangement.match; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.psi.codeStyle.arrangement.ArrangementEntry; import com.intellij.psi.codeStyle.arrangement.model.*; -import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; -import com.intellij.psi.codeStyle.arrangement.std.StdArrangementSettingsToken; -import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokenType; -import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens; +import com.intellij.psi.codeStyle.arrangement.std.*; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -129,8 +126,8 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher { * Maps token type to all arrangement tokens that were encountered so far by parsing conditions with * {@link #onCondition(ArrangementAtomMatchCondition) onCondition} calls. */ - @NotNull protected final MultiValuesMap context = - new MultiValuesMap(); + @NotNull protected final MultiValuesMap context = + new MultiValuesMap(); @Nullable private String myNamePattern; @Nullable private String myNamespacePattern; @Nullable private String myText; @@ -139,9 +136,9 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher { * Adds given entry to context by given entry type. * @param token token added to context */ - protected void addToContext(@NotNull StdArrangementSettingsToken token) { + protected void addToContext(@NotNull StdArrangementSettingsToken token, @NotNull ArrangementAtomMatchCondition condition) { StdArrangementTokenType tokenType = token.getTokenType(); - context.put(tokenType, token); + context.put(tokenType, condition); } @Override @@ -157,10 +154,10 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher { myText = condition.getValue().toString(); } Object v = condition.getValue(); - //Process any StdArrangementSettingsToken. No need to change it when new types of tokens will be processed. - if (v instanceof StdArrangementSettingsToken) { - StdArrangementSettingsToken token = (StdArrangementSettingsToken)v; - addToContext(token); + final ArrangementSettingsToken type = condition.getType(); + if (type instanceof StdArrangementSettingsToken) { + //Process any StdArrangementSettingsToken. No need to change it when new types of tokens will be processed. + addToContext((StdArrangementSettingsToken)type, condition); } } @@ -168,11 +165,11 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher { @Override public Collection buildMatchers() { List result = ContainerUtilRt.newArrayList(myMatchers); - Collection entryTokens = context.get(StdArrangementTokenType.ENTRY_TYPE); + Collection entryTokens = context.get(StdArrangementTokenType.ENTRY_TYPE); if (entryTokens!= null) { result.add(new ByTypeArrangementEntryMatcher(entryTokens)); } - Collection modifierTokens = context.get(StdArrangementTokenType.MODIFIER); + Collection modifierTokens = context.get(StdArrangementTokenType.MODIFIER); if (modifierTokens != null) { result.add(new ByModifierArrangementEntryMatcher(modifierTokens)); } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementMatchRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementMatchRule.java index 220f143010cc..26eb9d65ba63 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementMatchRule.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/StdArrangementMatchRule.java @@ -22,6 +22,7 @@ import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokenType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; import java.util.Set; /** @@ -55,8 +56,10 @@ public class StdArrangementMatchRule extends ArrangementMatchRule implements Clo @Override public int compareTo(@NotNull StdArrangementMatchRule o) { - final Set tokens = ArrangementUtil.extractTokens(getMatcher().getCondition()).keySet(); - final Set tokens1 = ArrangementUtil.extractTokens(o.getMatcher().getCondition()).keySet(); + final Map tokenValues = ArrangementUtil.extractTokens(getMatcher().getCondition()); + final Map tokenValues1 = ArrangementUtil.extractTokens(o.getMatcher().getCondition()); + final Set tokens = tokenValues.keySet(); + final Set tokens1 = tokenValues1.keySet(); if (tokens1.containsAll(tokens)) { return tokens.containsAll(tokens1) ? 0 : 1; } @@ -65,9 +68,9 @@ public class StdArrangementMatchRule extends ArrangementMatchRule implements Clo return -1; } - final String entryType = getEntryType(tokens); - final String entryType1 = getEntryType(tokens1); - final int compare = StringUtil.compare(entryType, entryType1, false); + final String entryType = getEntryType(tokenValues); + final String entryType1 = getEntryType(tokenValues1); + final int compare = StringUtil.compare(entryType1, entryType, false); if (compare != 0 || tokens.size() == tokens1.size()) { return compare; } @@ -76,10 +79,13 @@ public class StdArrangementMatchRule extends ArrangementMatchRule implements Clo } @Nullable - private static String getEntryType(@NotNull Set tokens) { - for (ArrangementSettingsToken token : tokens) { - if (StdArrangementTokenType.ENTRY_TYPE.is(token)) { - return token.getId(); + private static String getEntryType(@NotNull Map tokens) { + for (Map.Entry token : tokens.entrySet()) { + if (StdArrangementTokenType.ENTRY_TYPE.is(token.getKey())) { + final Object value = token.getValue(); + if (!(value instanceof Boolean) || (Boolean)value) { + return token.getKey().getId(); + } } } return null; diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementAtomMatchCondition.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementAtomMatchCondition.java index 31673d17586e..64f7ead73931 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementAtomMatchCondition.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementAtomMatchCondition.java @@ -16,6 +16,7 @@ package com.intellij.psi.codeStyle.arrangement.model; import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; +import com.intellij.psi.codeStyle.arrangement.std.InvertibleArrangementSettingsToken; import org.jetbrains.annotations.NotNull; /** @@ -31,10 +32,8 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition @NotNull private final ArrangementSettingsToken myType; @NotNull private final Object myValue; - private boolean myInverted; - public ArrangementAtomMatchCondition(@NotNull ArrangementSettingsToken type) { - this(type, type); + this(type, type instanceof InvertibleArrangementSettingsToken ? Boolean.TRUE : type); } public ArrangementAtomMatchCondition(@NotNull ArrangementSettingsToken type, @NotNull Object value) { @@ -57,15 +56,10 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition visitor.visit(this); } - public void setInverted(boolean inverted) { - myInverted = inverted; - } - @Override public int hashCode() { int result = myType.hashCode(); result = 31 * result + myValue.hashCode(); - result = 31 * result + (myInverted ? 1 : 0); return result; } @@ -80,9 +74,6 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition ArrangementAtomMatchCondition setting = (ArrangementAtomMatchCondition)o; - if (myInverted != setting.myInverted) { - return false; - } if (!myType.equals(setting.myType)) { return false; } @@ -96,18 +87,16 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition @NotNull @Override public ArrangementAtomMatchCondition clone() { - ArrangementAtomMatchCondition result = new ArrangementAtomMatchCondition(myType, myValue); - result.setInverted(myInverted); - return result; + return new ArrangementAtomMatchCondition(myType, myValue); } @Override public String toString() { - if (myType.equals(myValue)) { - return String.format("%s%s", myInverted ? "not " : "", myType.getRepresentationValue()); + if (myValue instanceof Boolean) { + return String.format("%s%s", (Boolean)myValue ? "" : "not " , myType.getRepresentationValue()); } else { - return String.format("%s: %s%s", myType.getRepresentationValue(), myInverted ? "not " : "", myValue.toString().toLowerCase()); + return String.format("%s: %s", myType.getRepresentationValue(), myValue.toString().toLowerCase()); } } } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementStandardSettingsManager.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementStandardSettingsManager.java index 55883c0d3b4b..5b3ccac7d3c8 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementStandardSettingsManager.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementStandardSettingsManager.java @@ -164,15 +164,22 @@ public class ArrangementStandardSettingsManager { private int parseWidth(@NotNull ArrangementSettingsToken token, @NotNull SimpleColoredComponent renderer) { renderer.clear(); - renderer.append(token.getRepresentationValue(), - SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, true))); + final String value = getPresentationValue(token); + renderer.append(value, SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, true))); int result = renderer.getPreferredSize().width; renderer.clear(); - renderer.append(token.getRepresentationValue(), - SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, false))); + renderer.append(value, SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, false))); return Math.max(result, renderer.getPreferredSize().width); } + + @NotNull + private static String getPresentationValue(@NotNull ArrangementSettingsToken token) { + if (token instanceof InvertibleArrangementSettingsToken) { + return ((InvertibleArrangementSettingsToken)token).getInvertedRepresentationValue(); + } + return token.getRepresentationValue(); + } public List sort(@NotNull Collection tokens) { List result = ContainerUtilRt.newArrayList(tokens); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementUiComponent.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementUiComponent.java index b752647c12d8..e76818e3cf48 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementUiComponent.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/ArrangementUiComponent.java @@ -36,7 +36,7 @@ import java.util.Set; * @since 3/11/13 10:22 AM */ public interface ArrangementUiComponent { - + @Nullable ArrangementSettingsToken getToken(); @NotNull Set getAvailableTokens(); @@ -107,7 +107,20 @@ public interface ArrangementUiComponent { int getBaselineToUse(int width, int height); void setListener(@NotNull Listener listener); - + + /** + * Method to process second click on the component, + * e.g. we can deselect the component or invert it condition + */ + void handleMouseClickOnSelected(); + + /** + * For condition that can't be disabled, + * e.g. 'not public' can be used with any other rule like 'private' or 'not private' + * @return + */ + boolean alwaysCanBeActive(); + interface Factory { ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.rearranger.ui"); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/InvertibleArrangementSettingsToken.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/InvertibleArrangementSettingsToken.java new file mode 100644 index 000000000000..0298ab9184b2 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/InvertibleArrangementSettingsToken.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2014 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.arrangement.std; + +import org.jetbrains.annotations.NotNull; + +/** + * Tokens that can be used in conditions in inverted state, + * e.g. 'public' -> 'not public' unlike 'order' or 'name' that can't be inverted + * + * @author Svetlana.Zemlyanskaya + */ +public interface InvertibleArrangementSettingsToken { + + /** + * Inverted representation value that will be used in UI + */ + @NotNull + String getInvertedRepresentationValue(); +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementSettingsToken.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementSettingsToken.java index d6503f56e6f3..2ddbf02c9aec 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementSettingsToken.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementSettingsToken.java @@ -52,9 +52,9 @@ public class StdArrangementSettingsToken extends ArrangementSettingsToken { return myTokenType; } - private StdArrangementSettingsToken(@NotNull String id, - @NotNull String uiName, - @NotNull StdArrangementTokenType tokenType) { + protected StdArrangementSettingsToken(@NotNull String id, + @NotNull String uiName, + @NotNull StdArrangementTokenType tokenType) { super(id, uiName); myTokenType = tokenType; } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementTokens.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementTokens.java index 61ebcdb97ace..15770aded615 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementTokens.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdArrangementTokens.java @@ -87,6 +87,12 @@ public class StdArrangementTokens { }; } + private static StdArrangementSettingsToken invertible(@NotNull String id, @NotNull StdArrangementTokenType type) { + StdArrangementSettingsToken result = StdInvertibleArrangementSettingsToken.invertibleTokenById(id, type); + TOKENS_BY_ID.put(id, result); + return result; + } + private static StdArrangementSettingsToken token(@NotNull String id, @NotNull StdArrangementTokenType type) { StdArrangementSettingsToken result = StdArrangementSettingsToken.tokenById(id, type); TOKENS_BY_ID.put(id, result); @@ -132,20 +138,23 @@ public class StdArrangementTokens { } } public static class EntryType { - @NotNull public static final ArrangementSettingsToken CLASS = token("CLASS", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken ANONYMOUS_CLASS = token("ANONYMOUS_CLASS", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken FIELD = token("FIELD", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken CONSTRUCTOR = token("CONSTRUCTOR", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken METHOD = token("METHOD", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken ENUM = token("ENUM", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken INTERFACE = token("INTERFACE", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken CONST = token("CONST", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken VAR = token("VAR", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken PROPERTY = token("PROPERTY", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken EVENT_HANDLER = token("EVENT_HANDLER", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken STATIC_INIT = token("STATIC_INIT", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken NAMESPACE = token("NAMESPACE", StdArrangementTokenType.ENTRY_TYPE); - @NotNull public static final ArrangementSettingsToken TRAIT = token("TRAIT", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken CLASS = invertible("CLASS", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken ANONYMOUS_CLASS = invertible("ANONYMOUS_CLASS", + StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken FIELD = invertible("FIELD", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken CONSTRUCTOR = invertible("CONSTRUCTOR", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken METHOD = invertible("METHOD", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken ENUM = invertible("ENUM", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken INTERFACE = invertible("INTERFACE", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken CONST = invertible("CONST", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken VAR = invertible("VAR", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken PROPERTY = invertible("PROPERTY", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken EVENT_HANDLER = invertible("EVENT_HANDLER", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken STATIC_INIT = invertible("STATIC_INIT", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken NAMESPACE = invertible("NAMESPACE", StdArrangementTokenType.ENTRY_TYPE); + @NotNull public static final ArrangementSettingsToken TRAIT = invertible("TRAIT", StdArrangementTokenType.ENTRY_TYPE); + + // xml use only two entry types -> invertible tokens make no sense @NotNull public static final ArrangementSettingsToken XML_TAG = token("XML_TAG", "arrangement.settings.text.entry.type.xml.tag", StdArrangementTokenType.ENTRY_TYPE); @NotNull public static final StdArrangementSettingsToken XML_ATTRIBUTE = @@ -162,17 +171,17 @@ public class StdArrangementTokens { } } public static class Modifier { - @NotNull public static final ArrangementSettingsToken PUBLIC = token("PUBLIC", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken PROTECTED = token("PROTECTED", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken PRIVATE = token("PRIVATE", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken PACKAGE_PRIVATE = token("PACKAGE_PRIVATE", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken STATIC = token("STATIC", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken FINAL = token("FINAL", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken TRANSIENT = token("TRANSIENT", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken VOLATILE = token("VOLATILE", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken SYNCHRONIZED = token("SYNCHRONIZED", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken ABSTRACT = token("ABSTRACT", StdArrangementTokenType.MODIFIER); - @NotNull public static final ArrangementSettingsToken OVERRIDE = token("OVERRIDE", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken PUBLIC = invertible("PUBLIC", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken PROTECTED = invertible("PROTECTED", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken PRIVATE = invertible("PRIVATE", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken PACKAGE_PRIVATE = invertible("PACKAGE_PRIVATE", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken STATIC = invertible("STATIC", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken FINAL = invertible("FINAL", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken TRANSIENT = invertible("TRANSIENT", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken VOLATILE = invertible("VOLATILE", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken SYNCHRONIZED = invertible("SYNCHRONIZED", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken ABSTRACT = invertible("ABSTRACT", StdArrangementTokenType.MODIFIER); + @NotNull public static final ArrangementSettingsToken OVERRIDE = invertible("OVERRIDE", StdArrangementTokenType.MODIFIER); private static final NotNullLazyValue> TOKENS = collectFields(Modifier.class); private Modifier() { diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdInvertibleArrangementSettingsToken.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdInvertibleArrangementSettingsToken.java new file mode 100644 index 000000000000..3a1fbab38851 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/std/StdInvertibleArrangementSettingsToken.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 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.arrangement.std; + +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class StdInvertibleArrangementSettingsToken extends StdArrangementSettingsToken implements InvertibleArrangementSettingsToken { + private static final String NOT = "not "; + + private StdInvertibleArrangementSettingsToken(@NotNull String id, + @NotNull String uiName, + @NotNull StdArrangementTokenType tokenType) { + super(id, uiName, tokenType); + } + + @NotNull + public static StdInvertibleArrangementSettingsToken invertibleTokenById(@NonNls @NotNull String id, + @NotNull StdArrangementTokenType tokenType) { + return new StdInvertibleArrangementSettingsToken(id, id.toLowerCase().replace("_", " "), tokenType); + } + + @NotNull + @Override + public String getInvertedRepresentationValue() { + return NOT + getRepresentationValue(); + } +} diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/AbstractArrangementUiComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/AbstractArrangementUiComponent.java index ca508a8f86df..094e6c53e04a 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/AbstractArrangementUiComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/AbstractArrangementUiComponent.java @@ -175,4 +175,9 @@ public abstract class AbstractArrangementUiComponent implements ArrangementUiCom } protected abstract void doReset(); + + @Override + public boolean alwaysCanBeActive() { + return false; + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAndMatchConditionComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAndMatchConditionComponent.java index 44b640dbea08..137519fc2742 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAndMatchConditionComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAndMatchConditionComponent.java @@ -16,7 +16,7 @@ package com.intellij.application.options.codeStyle.arrangement.component; import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants; -import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager; +import com.intellij.psi.codeStyle.arrangement.std.*; import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchNodeComponentFactory; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule; @@ -24,8 +24,6 @@ import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchConditio import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchConditionVisitor; -import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; -import com.intellij.psi.codeStyle.arrangement.std.ArrangementUiComponent; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; @@ -265,6 +263,18 @@ public class ArrangementAndMatchConditionComponent extends JPanel implements Arr } } + @Override + public void handleMouseClickOnSelected() { + for (ArrangementUiComponent component : myComponents) { + component.handleMouseClickOnSelected(); + } + } + + @Override + public boolean alwaysCanBeActive() { + return false; + } + @Override public String toString() { return String.format("(%s)", StringUtil.join(myComponents, " and ")); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAtomMatchConditionComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAtomMatchConditionComponent.java index f863088fc07b..d77225868c70 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAtomMatchConditionComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementAtomMatchConditionComponent.java @@ -22,6 +22,7 @@ import com.intellij.application.options.codeStyle.arrangement.color.ArrangementC import com.intellij.application.options.codeStyle.arrangement.util.InsetsPanel; import com.intellij.openapi.actionSystem.impl.ActionButton; import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; import com.intellij.psi.codeStyle.arrangement.std.*; import com.intellij.ui.IdeBorderFactory; @@ -97,10 +98,15 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp @Nullable private Rectangle myScreenBounds; @Nullable private Listener myListener; + private boolean myInverted = false; private boolean myEnabled = true; private boolean mySelected; private boolean myCloseButtonHovered; + // cached value for inverted atom condition, e.g. condition: 'static', opposite: 'not static' + @Nullable private ArrangementAtomMatchCondition myOppositeCondition; + @Nullable private String myInvertedText; + public ArrangementAtomMatchConditionComponent(@NotNull ArrangementStandardSettingsManager manager, @NotNull ArrangementColorsProvider colorsProvider, @NotNull ArrangementAtomMatchCondition condition, @@ -117,7 +123,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp else { myBorderStrategy = PREDEFINED_BORDER_STRATEGY; } - if (type.equals(condition.getValue())) { + if (type.equals(condition.getValue()) || condition.getValue() instanceof Boolean) { myText = type.getRepresentationValue(); } else if (StdArrangementTokenType.REG_EXP.is(type)) { @@ -225,17 +231,27 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp if (myCloseButton != null) { myCloseButton.setVisible(false); } + setData(myCondition.getValue()); } @NotNull @Override public ArrangementAtomMatchCondition getMatchCondition() { + if (myInverted == myCondition.getValue()) { + if (myOppositeCondition == null) { + myOppositeCondition = new ArrangementAtomMatchCondition(myCondition.getType(), !myInverted); + } + return myOppositeCondition; + } return myCondition; } @Override public void setData(@NotNull Object data) { - // Do nothing + if (data instanceof Boolean && myCondition.getType() instanceof InvertibleArrangementSettingsToken) { + myInverted = !((Boolean)data); + updateComponentText(mySelected); + } } @NotNull @@ -259,9 +275,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp public void setSelected(boolean selected) { boolean notifyListener = selected != mySelected; mySelected = selected; - myTextControl.clear(); - TextAttributes attributes = myColorsProvider.getTextAttributes(myCondition.getType(), selected); - myTextControl.append(myText, SimpleTextAttributes.fromTextAttributes(attributes)); + TextAttributes attributes = updateComponentText(selected); myBorder.setColor(myColorsProvider.getBorderColor(selected)); myBackgroundColor = attributes.getBackgroundColor(); if (notifyListener && myListener != null) { @@ -269,6 +283,26 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp } } + @NotNull + private TextAttributes updateComponentText(boolean selected) { + myTextControl.clear(); + TextAttributes attributes = myColorsProvider.getTextAttributes(myCondition.getType(), selected); + myTextControl.append(getComponentText(), SimpleTextAttributes.fromTextAttributes(attributes)); + return attributes; + } + + private String getComponentText() { + if (myInverted) { + if (StringUtil.isEmpty(myInvertedText)) { + final ArrangementSettingsToken token = myCondition.getType(); + assert token instanceof InvertibleArrangementSettingsToken; + myInvertedText = ((InvertibleArrangementSettingsToken)token).getInvertedRepresentationValue(); + } + return myInvertedText; + } + return myText; + } + @Override public boolean isEnabled() { return myEnabled; @@ -349,7 +383,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp @Override public String toString() { - return myText; + return getComponentText(); } @NotNull @@ -377,6 +411,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp @Override public void reset() { setSelected(false); + setData(true); } @Override @@ -390,6 +425,19 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp myListener = listener; } + @Override + public void handleMouseClickOnSelected() { + if (myInverted) { + setSelected(false); + } + setData(myInverted); + } + + @Override + public boolean alwaysCanBeActive() { + return myInverted; + } + private interface BorderStrategy { RoundedLineBorder create(); void setup(@NotNull Graphics2D g); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementCheckBoxUiComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementCheckBoxUiComponent.java index 214b036ce845..053585c7c854 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementCheckBoxUiComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementCheckBoxUiComponent.java @@ -115,11 +115,16 @@ public class ArrangementCheckBoxUiComponent extends AbstractArrangementUiCompone @Override public void setSelected(boolean selected) { - myCheckBox.setSelected(selected); + myCheckBox.setSelected(selected); } @Override public int getBaselineToUse(int width, int height) { return myTextLabel.getBaseline(width, height); } + + @Override + public void handleMouseClickOnSelected() { + setSelected(false); + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementComboBoxUiComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementComboBoxUiComponent.java index cad3fc88ca22..9cfce2abc0ab 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementComboBoxUiComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementComboBoxUiComponent.java @@ -123,4 +123,9 @@ public class ArrangementComboBoxUiComponent extends AbstractArrangementUiCompone public int getBaselineToUse(int width, int height) { return -1; } + + @Override + public void handleMouseClickOnSelected() { + setSelected(false); + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementLabelUiComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementLabelUiComponent.java index 9d89b728e40d..bdb7503f53c1 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementLabelUiComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementLabelUiComponent.java @@ -85,4 +85,9 @@ public class ArrangementLabelUiComponent extends AbstractArrangementUiComponent public int getBaselineToUse(int width, int height) { return myLabel.getBaseline(width, height); } + + @Override + public void handleMouseClickOnSelected() { + setSelected(false); + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementTextFieldUiComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementTextFieldUiComponent.java index dae8d6ba8a88..0e93b8a97ba1 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementTextFieldUiComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/component/ArrangementTextFieldUiComponent.java @@ -114,7 +114,9 @@ public class ArrangementTextFieldUiComponent extends AbstractArrangementUiCompon @Override public void setData(@NotNull Object data) { - myTextField.setText(data.toString()); + if (data instanceof String) { + myTextField.setText(data.toString()); + } } @Override @@ -126,4 +128,9 @@ public class ArrangementTextFieldUiComponent extends AbstractArrangementUiCompon public int getBaselineToUse(int width, int height) { return myTextField.getBaseline(width, height); } + + @Override + public void handleMouseClickOnSelected() { + setSelected(false); + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRuleEditor.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRuleEditor.java index 4f2ed17842e2..0c51dd5fc0ea 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRuleEditor.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRuleEditor.java @@ -378,7 +378,8 @@ public class ArrangementMatchingRuleEditor extends JPanel implements Arrangement // don't allow to remove start/end section indication final Set mutexes = ArrangementSectionRuleManager.getSectionMutexes(); if (!mutexes.contains(component.getToken())) { - removeCondition(component); + component.handleMouseClickOnSelected(); + refreshConditions(); } } else { @@ -417,7 +418,7 @@ public class ArrangementMatchingRuleEditor extends JPanel implements Arrangement continue; } ArrangementUiComponent c = myComponents.get(key); - if (c != null && c.isEnabled()) { + if (c != null && c.isEnabled() && !c.alwaysCanBeActive()) { removeCondition(c); } } @@ -425,6 +426,7 @@ public class ArrangementMatchingRuleEditor extends JPanel implements Arrangement private void removeCondition(@NotNull ArrangementUiComponent component) { component.setSelected(false); + component.setData(true); refreshConditions(); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementListRowDecorator.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementListRowDecorator.java index 5bbba9eb8a7c..897c9cd22fd3 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementListRowDecorator.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementListRowDecorator.java @@ -280,6 +280,16 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementUi myDelegate.setListener(listener); } + @Override + public void handleMouseClickOnSelected() { + myDelegate.handleMouseClickOnSelected(); + } + + @Override + public boolean alwaysCanBeActive() { + return false; + } + @Override public String toString() { return "list row decorator for " + myDelegate.toString(); diff --git a/platform/testFramework/testSrc/com/intellij/psi/codeStyle/arrangement/AbstractRearrangerTest.java b/platform/testFramework/testSrc/com/intellij/psi/codeStyle/arrangement/AbstractRearrangerTest.java index 92c2723ce3b5..b503f5cf1e59 100644 --- a/platform/testFramework/testSrc/com/intellij/psi/codeStyle/arrangement/AbstractRearrangerTest.java +++ b/platform/testFramework/testSrc/com/intellij/psi/codeStyle/arrangement/AbstractRearrangerTest.java @@ -142,6 +142,10 @@ public abstract class AbstractRearrangerTest extends LightPlatformCodeInsightFix return new ArrangementAtomMatchCondition(token); } + protected static ArrangementAtomMatchCondition atom(@NotNull ArrangementSettingsToken token, boolean included) { + return new ArrangementAtomMatchCondition(token, included); + } + @NotNull protected static ArrangementAtomMatchCondition atom(@NotNull String nameFilter) { return new ArrangementAtomMatchCondition(StdArrangementTokens.Regexp.NAME, nameFilter);