IDEA-95126 Arrangement: Provide ability to negate conditions

This commit is contained in:
Svetlana.Zemlyanskay
2014-10-06 17:28:37 +04:00
parent b9a02c8cfc
commit c02bf6506f
23 changed files with 338 additions and 100 deletions
@@ -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());
@@ -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<ArrangementSettingsToken> myModifiers = ContainerUtilRt.newHashSet();
@NotNull private final Set<ArrangementAtomMatchCondition> myModifiers = ContainerUtilRt.newHashSet();
public ByModifierArrangementEntryMatcher(@NotNull ArrangementSettingsToken interestedModifier) {
public ByModifierArrangementEntryMatcher(@NotNull ArrangementAtomMatchCondition interestedModifier) {
myModifiers.add(interestedModifier);
}
public ByModifierArrangementEntryMatcher(@NotNull Collection<ArrangementSettingsToken> interestedModifiers) {
public ByModifierArrangementEntryMatcher(@NotNull Collection<ArrangementAtomMatchCondition> interestedModifiers) {
myModifiers.addAll(interestedModifiers);
}
@Override
public boolean isMatched(@NotNull ArrangementEntry entry) {
if (entry instanceof ModifierAwareArrangementEntry) {
return ((ModifierAwareArrangementEntry)entry).getModifiers().containsAll(myModifiers);
final Set<ArrangementSettingsToken> 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;
}
@@ -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<ArrangementSettingsToken> myTypes = ContainerUtilRt.newHashSet();
@NotNull private final Set<ArrangementAtomMatchCondition> myTypes = ContainerUtilRt.newHashSet();
public ByTypeArrangementEntryMatcher(@NotNull ArrangementSettingsToken interestedType) {
public ByTypeArrangementEntryMatcher(@NotNull ArrangementAtomMatchCondition interestedType) {
myTypes.add(interestedType);
}
public ByTypeArrangementEntryMatcher(@NotNull Collection<ArrangementSettingsToken> interestedTypes) {
public ByTypeArrangementEntryMatcher(@NotNull Collection<ArrangementAtomMatchCondition> interestedTypes) {
myTypes.addAll(interestedTypes);
}
@Override
public boolean isMatched(@NotNull ArrangementEntry entry) {
if (entry instanceof TypeAwareArrangementEntry) {
return ((TypeAwareArrangementEntry)entry).getTypes().containsAll(myTypes);
final Set<ArrangementSettingsToken> 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<ArrangementSettingsToken> getTypes() {
public Set<ArrangementAtomMatchCondition> getTypes() {
return myTypes;
}
@@ -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);
}
@@ -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<StdArrangementTokenType, ArrangementSettingsToken > context =
new MultiValuesMap<StdArrangementTokenType, ArrangementSettingsToken>();
@NotNull protected final MultiValuesMap<StdArrangementTokenType, ArrangementAtomMatchCondition> context =
new MultiValuesMap<StdArrangementTokenType, ArrangementAtomMatchCondition>();
@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<ArrangementEntryMatcher> buildMatchers() {
List<ArrangementEntryMatcher> result = ContainerUtilRt.newArrayList(myMatchers);
Collection<ArrangementSettingsToken> entryTokens = context.get(StdArrangementTokenType.ENTRY_TYPE);
Collection<ArrangementAtomMatchCondition> entryTokens = context.get(StdArrangementTokenType.ENTRY_TYPE);
if (entryTokens!= null) {
result.add(new ByTypeArrangementEntryMatcher(entryTokens));
}
Collection<ArrangementSettingsToken> modifierTokens = context.get(StdArrangementTokenType.MODIFIER);
Collection<ArrangementAtomMatchCondition> modifierTokens = context.get(StdArrangementTokenType.MODIFIER);
if (modifierTokens != null) {
result.add(new ByModifierArrangementEntryMatcher(modifierTokens));
}
@@ -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<ArrangementSettingsToken> tokens = ArrangementUtil.extractTokens(getMatcher().getCondition()).keySet();
final Set<ArrangementSettingsToken> tokens1 = ArrangementUtil.extractTokens(o.getMatcher().getCondition()).keySet();
final Map<ArrangementSettingsToken, Object> tokenValues = ArrangementUtil.extractTokens(getMatcher().getCondition());
final Map<ArrangementSettingsToken, Object> tokenValues1 = ArrangementUtil.extractTokens(o.getMatcher().getCondition());
final Set<ArrangementSettingsToken> tokens = tokenValues.keySet();
final Set<ArrangementSettingsToken> 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<ArrangementSettingsToken> tokens) {
for (ArrangementSettingsToken token : tokens) {
if (StdArrangementTokenType.ENTRY_TYPE.is(token)) {
return token.getId();
private static String getEntryType(@NotNull Map<ArrangementSettingsToken, Object> tokens) {
for (Map.Entry<ArrangementSettingsToken, Object> 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;
@@ -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());
}
}
}
@@ -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<ArrangementSettingsToken> sort(@NotNull Collection<ArrangementSettingsToken> tokens) {
List<ArrangementSettingsToken> result = ContainerUtilRt.newArrayList(tokens);
@@ -36,7 +36,7 @@ import java.util.Set;
* @since 3/11/13 10:22 AM
*/
public interface ArrangementUiComponent {
@Nullable ArrangementSettingsToken getToken();
@NotNull Set<ArrangementSettingsToken> 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<Factory> EP_NAME = ExtensionPointName.create("com.intellij.rearranger.ui");
@@ -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();
}
@@ -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;
}
@@ -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<Set<ArrangementSettingsToken>> TOKENS = collectFields(Modifier.class);
private Modifier() {
@@ -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();
}
}
@@ -175,4 +175,9 @@ public abstract class AbstractArrangementUiComponent implements ArrangementUiCom
}
protected abstract void doReset();
@Override
public boolean alwaysCanBeActive() {
return false;
}
}
@@ -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 "));
@@ -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);
@@ -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);
}
}
@@ -123,4 +123,9 @@ public class ArrangementComboBoxUiComponent extends AbstractArrangementUiCompone
public int getBaselineToUse(int width, int height) {
return -1;
}
@Override
public void handleMouseClickOnSelected() {
setSelected(false);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -378,7 +378,8 @@ public class ArrangementMatchingRuleEditor extends JPanel implements Arrangement
// don't allow to remove start/end section indication
final Set<ArrangementSettingsToken> 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();
}
@@ -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();
@@ -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);