Merge branch 'uta/rainbow'

This commit is contained in:
Alexey Utkin
2016-09-02 12:28:57 +03:00
36 changed files with 1284 additions and 399 deletions
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.JavaHighlightInfoTypes;
import com.intellij.lang.ASTNode;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.colors.TextAttributesScheme;
@@ -154,7 +155,9 @@ public class HighlightNamesUtil {
}
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(varType).range(elementToHighlight);
return RainbowHighlighter.isRainbowEnabled() ? builder.createUnconditionally() : builder.create();
return RainbowHighlighter.isRainbowEnabledWithInheritance(colorsScheme, JavaLanguage.INSTANCE)
? builder.createUnconditionally()
: builder.create();
}
@Nullable
@@ -16,8 +16,12 @@
package com.intellij.openapi.options.colors.pages;
import com.intellij.application.options.colors.InspectionColorSettingsPage;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.ide.highlighter.JavaFileHighlighter;
import com.intellij.ide.highlighter.JavaHighlightingColors;
import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.StdFileTypes;
@@ -25,18 +29,18 @@ import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.colors.AttributesDescriptor;
import com.intellij.openapi.options.colors.ColorDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.openapi.options.colors.RainbowColorSettingsPage;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.codeStyle.DisplayPriority;
import com.intellij.psi.codeStyle.DisplayPrioritySortable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map;
public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColorSettingsPage, DisplayPrioritySortable {
public class JavaColorSettingsPage implements RainbowColorSettingsPage, InspectionColorSettingsPage, DisplayPrioritySortable {
private static final AttributesDescriptor[] ourDescriptors = {
new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.keyword"), JavaHighlightingColors.KEYWORD),
new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.number"), JavaHighlightingColors.NUMBER),
@@ -89,7 +93,7 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor
new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.annotation.attribute.name"), JavaHighlightingColors.ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES)
};
@NonNls private static final Map<String, TextAttributesKey> ourTags = new HashMap<>();
@NonNls private static final Map<String, TextAttributesKey> ourTags = RainbowHighlighter.createRainbowHLM();
static {
ourTags.put("field", JavaHighlightingColors.INSTANCE_FIELD_ATTRIBUTES);
ourTags.put("unusedField", CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES);
@@ -175,11 +179,22 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor
" public static int <static>staticField</static> = 0;\n" +
" public final int <instanceFinalField>instanceFinalField</instanceFinalField> = 0;\n" +
"\n" +
" public <constructorDeclaration>SomeClass</constructorDeclaration>(<interface>AnInterface</interface> <param>param</param>, int[] <reassignedParameter>reassignedParam</reassignedParameter>) {\n" +
" /**\n" +
" * " + ApplicationBundle.message("rainbow.option.panel.display.name") + ":\n" +
" * " + RainbowHighlighter.generatePaletteExample() + "\n" +
" * @param <javadocTagValue>param1</javadocTagValue>\n" +
" * @param <javadocTagValue>reassignedParam</javadocTagValue>\n" +
" * @param <javadocTagValue>param2</javadocTagValue>\n" +
" * @param <javadocTagValue>param3</javadocTagValue>\n" +
" */\n" +
" public <constructorDeclaration>SomeClass</constructorDeclaration>(<interface>AnInterface</interface> <param>param1</param>, int[] <reassignedParameter>reassignedParam</reassignedParameter>,\n" +
" int <param>param2</param>\n" +
" int <param>param3</param>) {\n" +
" int <reassignedLocalVar>reassignedValue</reassignedLocalVar> = this.<warning>staticField</warning> + <param>param2</param> + <param>param3</param>;\n" +
" long <localVar>localVar1</localVar>, <localVar>localVar2</localVar>, <localVar>localVar3</localVar>, <localVar>localVar4</localVar>;\n" +
" <error>int <localVar>localVar</localVar> = \"IntelliJ\"</error>; // Error, incompatible types\n" +
" <class>System</class>.<static>out</static>.<methodCall>println</methodCall>(<field>anotherString</field> + <inherited_method>toString</inherited_method>() + <localVar>localVar</localVar>);\n" +
" long <localVar>time</localVar> = <class>Date</class>.<static_method><deprecated>parse</deprecated></static_method>(\"1.2.3\"); // Method is deprecated\n" +
" int <reassignedLocalVar>reassignedValue</reassignedLocalVar> = this.<warning>staticField</warning>; \n" +
" <reassignedLocalVar>reassignedValue</reassignedLocalVar> ++; \n" +
" <field>field</field>.<abstract_method>run</abstract_method>(); \n" +
" new <anonymousClass>SomeClass</anonymousClass>() {\n" +
@@ -190,7 +205,7 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor
" <reassignedParameter>reassignedParam</reassignedParameter> = new <constructorCall>ArrayList</constructorCall><<class>String</class>>().toArray(new int[0]);\n" +
" }\n" +
"}\n" +
"enum <enum>AnEnum</enum> { <static_final>CONST1</static_final>, <static_final>CONST2</static_final> }\n"+
"enum <enum>AnEnum</enum> { <static_final>CONST1</static_final>, <static_final>CONST2</static_final> }\n" +
"interface <interface>AnInterface</interface> {\n" +
" int <static_final>CONSTANT</static_final> = 2;\n" +
" void <methodDeclaration>method</methodDeclaration>();\n" +
@@ -208,4 +223,19 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor
public DisplayPriority getPriority() {
return DisplayPriority.KEY_LANGUAGE_SETTINGS;
}
@Override
public boolean isRainbowType(TextAttributesKey type) {
return JavaHighlightingColors.LOCAL_VARIABLE_ATTRIBUTES.equals(type)
|| JavaHighlightingColors.REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES.equals(type)
|| JavaHighlightingColors.PARAMETER_ATTRIBUTES.equals(type)
|| JavaHighlightingColors.REASSIGNED_PARAMETER_ATTRIBUTES.equals(type)
|| JavaHighlightingColors.DOC_COMMENT_TAG_VALUE.equals(type);
}
@Nullable
@Override
public Language getLanguage() {
return JavaLanguage.INSTANCE;
}
}
@@ -17,6 +17,7 @@ package com.intellij.codeHighlighting;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.lang.Language;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
@@ -24,17 +25,22 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.colors.TextAttributesScheme;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.options.SchemeMetaInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.JBColor;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class RainbowHighlighter {
private static final JBColor[] RAINBOW_JB_COLORS_DEFAULT = {
@@ -44,16 +50,25 @@ public class RainbowHighlighter {
new JBColor(0x005910, 0xbe9970),
new JBColor(0xbc5150, 0x9d527c),
};
private static final TextAttributesKey[] RAINBOW_COLOR_KEYS = new TextAttributesKey[RAINBOW_JB_COLORS_DEFAULT.length];
public static final TextAttributesKey[] RAINBOW_COLOR_KEYS = new TextAttributesKey[RAINBOW_JB_COLORS_DEFAULT.length];
private static final int RAINBOW_COLORS_BETWEEN = 4;
private static final String UNIT_TEST_COLORS = "#000001,#000002,#000003,#000004"; // Do not modify!
private static final String INHERITED = "inherited";
static {
for (int i = 0; i < RAINBOW_JB_COLORS_DEFAULT.length; ++i) {
JBColor jbColor = RAINBOW_JB_COLORS_DEFAULT[i];
TextAttributes textAttributes = new TextAttributes(jbColor, null, null, null, Font.PLAIN);
RAINBOW_COLOR_KEYS[i] = TextAttributesKey.createTextAttributesKey("RAINBOW_COLOR" + i, textAttributes);
//noinspection deprecation
RAINBOW_COLOR_KEYS[i] = TextAttributesKey.createTextAttributesKey("RAINBOW_COLOR" + i, createRainbowAttribute(RAINBOW_JB_COLORS_DEFAULT[i]));
}
}
public final static String RAINBOW_TYPE = "rainbow";
private final static String RAINBOW_TEMP_PREF = "RAINBOW_TEMP_";
@SuppressWarnings("deprecation")
public final static TextAttributesKey RAINBOW_ANCHOR = TextAttributesKey.createTextAttributesKey(RAINBOW_TYPE, new TextAttributes());
@SuppressWarnings("deprecation")
public final static TextAttributesKey RAINBOW_GRADIENT_DEMO = TextAttributesKey.createTextAttributesKey("rainbow_demo", new TextAttributes());
public final static Boolean DEFAULT_RAINBOW_ON = Boolean.FALSE;
@NotNull private final TextAttributesScheme myColorsScheme;
@NotNull private final Color[] myRainbowColors;
@@ -65,11 +80,57 @@ public class RainbowHighlighter {
public static final HighlightInfoType RAINBOW_ELEMENT = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, DefaultLanguageHighlighterColors.CONSTANT);
public static boolean isRainbowEnabled() {
return Registry.is("editor.rainbow.identifiers", false);
@Nullable
@Contract("_, null -> !null")
public static Boolean isRainbowEnabled(@Nullable TextAttributesScheme colorsScheme, @Nullable Language language) {
if (colorsScheme instanceof SchemeMetaInfo) {
String value = ((SchemeMetaInfo)colorsScheme).getMetaProperties().getProperty(getKey(language), INHERITED);
if (String.valueOf(true).equals(value)) return Boolean.TRUE;
if (String.valueOf(false).equals(value)) return Boolean.FALSE;
return language == null ? DEFAULT_RAINBOW_ON : null;
}
return false;
}
public static boolean isRainbowEnabledWithInheritance(@Nullable TextAttributesScheme colorsScheme, @Nullable Language language) {
Boolean rainbowEnabled = isRainbowEnabled(colorsScheme, language);
return rainbowEnabled != null ? rainbowEnabled : isRainbowEnabled(colorsScheme, null);
}
public static void setRainbowEnabled(@NotNull SchemeMetaInfo colorsScheme, @Nullable Language language, @Nullable Boolean enabled) {
Properties properties = colorsScheme.getMetaProperties();
String key = getKey(language);
if (enabled == null || (language == null && enabled == DEFAULT_RAINBOW_ON)) {
properties.remove(key);
}
else {
properties.setProperty(key, String.valueOf(enabled));
}
}
@NotNull
private static String getKey(@Nullable Language language) {
return RAINBOW_TYPE + " " + (language == null ? "Default language" : language.getID());
}
@NotNull
public static String generatePaletteExample() {
int stopCount = RAINBOW_COLOR_KEYS.length;
StringBuilder sb = new StringBuilder();
String tagRainbow = RAINBOW_GRADIENT_DEMO.getExternalName();
for (int i = 0; i < RAINBOW_TEMP_KEYS.length; ++i) {
if (sb.length() != 0) {
sb.append(" ");
}
sb.append("<").append(tagRainbow).append(">");
sb.append((i % stopCount == 0) ? "Stop#" + String.valueOf(i / stopCount + 1) : "T");
sb.append("</").append(tagRainbow).append(">");
}
return sb.toString();
}
@NotNull
@Contract(pure = true)
private Color calculateForeground(int colorIndex) {
return myRainbowColors[colorIndex];
}
@@ -89,15 +150,37 @@ public class RainbowHighlighter {
return registryColors.stream().map(s -> ColorUtil.fromHex(s.trim())).toArray(Color[]::new);
}
List<Color> foregroundColors = ContainerUtil.map(RAINBOW_COLOR_KEYS, key -> colorsScheme.getAttributes(key).getForegroundColor());
List<Color> colors = ColorGenerator.generateLinearColorSequence(foregroundColors, RAINBOW_COLORS_BETWEEN);
List<Color> stopColors = ContainerUtil.map(RAINBOW_COLOR_KEYS, key -> colorsScheme.getAttributes(key).getForegroundColor());
List<Color> colors = ColorGenerator.generateLinearColorSequence(stopColors, RAINBOW_COLORS_BETWEEN);
return colors.toArray(new Color[colors.size()]);
}
public HighlightInfo getInfo(int colorIndex, @Nullable PsiElement id, @Nullable TextAttributesKey colorKey) {
if (id == null) {
return null;
@NotNull
public TextAttributesKey[] getRainbowTempKeys() {
TextAttributesKey[] keys = new TextAttributesKey[myRainbowColors.length];
for (int i = 0; i < myRainbowColors.length; ++i) {
//noinspection deprecation
TextAttributesKey key = TextAttributesKey.createTextAttributesKey(RAINBOW_TEMP_PREF + i, new TextAttributes());
key.getDefaultAttributes().setForegroundColor(myRainbowColors[i]);
keys[i] = key;
}
return keys;
}
public static boolean isRainbowTempKey(TextAttributesKey key) {
return key.getExternalName().startsWith(RAINBOW_TEMP_PREF);
}
public HighlightInfo getInfo(int colorIndex, @Nullable PsiElement id, @Nullable TextAttributesKey colorKey) {
return id == null ? null : getInfoBuilder(colorIndex, colorKey).range(id).create();
}
public HighlightInfo getInfo(int colorIndex, int start, int end, @Nullable TextAttributesKey colorKey) {
return getInfoBuilder(colorIndex, colorKey).range(start, end).create();
}
@NotNull
protected HighlightInfo.Builder getInfoBuilder(int colorIndex, @Nullable TextAttributesKey colorKey) {
if (colorKey == null) {
colorKey = DefaultLanguageHighlighterColors.LOCAL_VARIABLE;
}
@@ -107,8 +190,25 @@ public class RainbowHighlighter {
.fromFlyweight(myColorsScheme
.getAttributes(colorKey)
.getFlyweight()
.withForeground(calculateForeground(colorIndex))))
.range(id)
.create();
.withForeground(calculateForeground(colorIndex))));
}
private static final TextAttributesKey[] RAINBOW_TEMP_KEYS = new RainbowHighlighter(null).getRainbowTempKeys();
@NotNull
public static TextAttributes createRainbowAttribute(@Nullable Color color) {
TextAttributes ret = new TextAttributes();
ret.setForegroundColor(color);
return ret;
}
public static Map<String, TextAttributesKey> createRainbowHLM() {
Map<String, TextAttributesKey> hashMap = new HashMap<>();
hashMap.put(RAINBOW_ANCHOR.getExternalName(), RAINBOW_ANCHOR);
hashMap.put(RAINBOW_GRADIENT_DEMO.getExternalName(), RAINBOW_GRADIENT_DEMO);
for (TextAttributesKey key : RAINBOW_TEMP_KEYS) {
hashMap.put(key.getExternalName(), key);
}
return hashMap;
}
}
@@ -69,7 +69,7 @@ public abstract class RainbowVisitor implements HighlightVisitor {
@NotNull final PsiElement rainbowElement,
@NotNull final String name,
@Nullable final TextAttributesKey colorKey) {
int colorIndex = UsedColors.getOrAddColorIndex((UserDataHolderEx)context, name, getHighlighter());
int colorIndex = UsedColors.getOrAddColorIndex((UserDataHolderEx)context, name, getHighlighter().getColorsCount());
return getHighlighter().getInfo(colorIndex, rainbowElement, colorKey);
}
}
@@ -15,16 +15,16 @@
*/
package com.intellij.codeInsight.daemon;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderEx;
import com.intellij.openapi.util.text.StringHash;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.atomic.AtomicInteger;
class UsedColors {
public class UsedColors {
private static final Key<Object/*UsedColor or UsedColor[]*/> USED_COLOR = Key.create("USED_COLOR");
public static final AtomicInteger counter = new AtomicInteger();
@@ -39,10 +39,9 @@ class UsedColors {
}
}
static int getOrAddColorIndex(@NotNull final UserDataHolderEx context,
@NotNull final String name,
@NotNull RainbowHighlighter rainbowHighlighter) {
int colorsCount = rainbowHighlighter.getColorsCount();
public static int getOrAddColorIndex(@NotNull final UserDataHolderEx context,
@NotNull final String name,
int colorsCount) {
int colorIndex;
while (true) {
Object data = context.getUserData(USED_COLOR);
@@ -101,6 +100,7 @@ class UsedColors {
return Math.abs(StringHash.murmur(name, 0x55AA)) % colorsCount;
}
@Contract(pure = true)
private static int indexOfMin(@NotNull int[] values, int start, int end) {
int min = Integer.MAX_VALUE;
int minIndex = start;
@@ -142,7 +142,8 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
final List<HighlightVisitor> visitors = new ArrayList<>(highlightVisitors.length);
List<HighlightVisitor> list = Arrays.asList(highlightVisitors);
for (HighlightVisitor visitor : DumbService.getInstance(myProject).filterByDumbAwareness(list)) {
if (visitor instanceof RainbowVisitor && !RainbowHighlighter.isRainbowEnabled()) {
if (visitor instanceof RainbowVisitor
&& !RainbowHighlighter.isRainbowEnabledWithInheritance(getColorsScheme(), psiFile.getLanguage())) {
continue;
}
if (visitor.suitableForFile(psiFile)) {
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2016 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.openapi.options;
import org.jetbrains.annotations.NotNull;
import java.util.Properties;
public interface SchemeMetaInfo {
@NotNull
Properties getMetaProperties();
}
@@ -18,6 +18,7 @@ package com.intellij.openapi.editor.colors;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.options.FontSize;
import com.intellij.openapi.options.Scheme;
import com.intellij.openapi.options.SchemeMetaInfo;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -25,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
public interface EditorColorsScheme extends Cloneable, TextAttributesScheme, Scheme {
public interface EditorColorsScheme extends Cloneable, TextAttributesScheme, Scheme, SchemeMetaInfo {
@NonNls String DEFAULT_SCHEME_NAME = "Default";
void setName(String name);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -14,9 +14,7 @@
* limitations under the License.
*/
package com.intellij.application.options.colors;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
package com.intellij.openapi.editor.colors;
public interface EditorSchemeAttributeDescriptor {
String getGroup();
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2016 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.openapi.editor.colors;
public interface EditorSchemeAttributeDescriptorWithPath extends EditorSchemeAttributeDescriptor {
String NAME_SEPARATOR = "//";
}
@@ -830,4 +830,10 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
}
public boolean isReadOnly() { return false; }
@NotNull
@Override
public Properties getMetaProperties() {
return myMetaInfo;
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2016 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.openapi.options.colors;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import org.jetbrains.annotations.Nullable;
public interface RainbowColorSettingsPage extends ColorSettingsPage {
boolean isRainbowType(TextAttributesKey type);
@Nullable
Language getLanguage();
}
@@ -1,180 +0,0 @@
/*
* Copyright 2000-2016 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.application.options.colors;
import com.intellij.application.options.colors.highlighting.HighlightData;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.HighlighterColors;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.psi.tree.IElementType;
import com.intellij.ui.ScrollingUtil;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.annotations.JdkConstants;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
public class ClickNavigator {
private final JList myOptionsList;
public ClickNavigator(JList optionsList) {
myOptionsList = optionsList;
}
public void addClickNavigatorToGeneralView(final Editor view) {
view.getContentComponent().addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
EditorUtil.setHandCursor(view);
}
});
CaretListener listener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
setSelectedItem(HighlighterColors.TEXT.getExternalName(), true);
}
};
view.getCaretModel().addCaretListener(listener);
}
private boolean setSelectedItem(String type, boolean select) {
DefaultListModel model = (DefaultListModel)myOptionsList.getModel();
for (int i = 0; i < model.size(); i++) {
Object o = model.get(i);
if (o instanceof EditorSchemeAttributeDescriptor) {
if (type.equals(((EditorSchemeAttributeDescriptor)o).getType())) {
if (select) {
ScrollingUtil.selectItem(myOptionsList, i);
}
return true;
}
}
}
return false;
}
private static boolean isWhiteSpace(int offset, CharSequence text) {
return offset <= 0 || offset >= text.length() ||
text.charAt(offset) == ' ' || text.charAt(offset) == '\t' ||
text.charAt(offset) == '\n' || text.charAt(offset) == '\r';
}
public static boolean highlightDataContainsOffset(HighlightData data, int offset) {
return offset >= data.getStartOffset() && offset <= data.getEndOffset();
}
public void addClickNavigator(final Editor view,
final SyntaxHighlighter highlighter,
final HighlightData[] data,
final boolean isBackgroundImportant) {
addMouseMotionListener(view, highlighter, data, isBackgroundImportant);
CaretListener listener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
navigate(view, true, e.getNewPosition(), highlighter, data, isBackgroundImportant);
}
};
view.getCaretModel().addCaretListener(listener);
}
private boolean selectItem(boolean select, HighlighterIterator itr, SyntaxHighlighter highlighter) {
IElementType tokenType = itr.getTokenType();
if (tokenType == null) return false;
String type = highlightingTypeFromTokenType(tokenType, highlighter);
return setSelectedItem(type, select);
}
public static String highlightingTypeFromTokenType(IElementType tokenType, SyntaxHighlighter highlighter) {
TextAttributesKey[] highlights = highlighter.getTokenHighlights(tokenType);
String s = null;
for (int i = highlights.length - 1; i >= 0; i--) {
if (highlights[i] != HighlighterColors.TEXT) {
s = highlights[i].getExternalName();
break;
}
}
return s == null ? HighlighterColors.TEXT.getExternalName() : s;
}
private void addMouseMotionListener(final Editor view,
final SyntaxHighlighter highlighter,
final HighlightData[] data, final boolean isBackgroundImportant) {
view.getContentComponent().addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
LogicalPosition pos = view.xyToLogicalPosition(new Point(e.getX(), e.getY()));
navigate(view, false, pos, highlighter, data, isBackgroundImportant);
}
});
}
private void navigate(final Editor editor, boolean select,
LogicalPosition pos,
final SyntaxHighlighter highlighter,
final HighlightData[] data, final boolean isBackgroundImportant) {
int offset = editor.logicalPositionToOffset(pos);
if (!isBackgroundImportant && editor.offsetToLogicalPosition(offset).column != pos.column) {
if (!select) {
setCursor(editor, Cursor.TEXT_CURSOR);
return;
}
}
if (data != null) {
for (HighlightData highlightData : data) {
if (highlightDataContainsOffset(highlightData, editor.logicalPositionToOffset(pos))) {
if (!select) setCursor(editor, Cursor.HAND_CURSOR);
setSelectedItem(highlightData.getHighlightType(), select);
return;
}
}
}
if (highlighter != null) {
HighlighterIterator itr = ((EditorEx)editor).getHighlighter().createIterator(offset);
boolean selection = selectItem(select, itr, highlighter);
if (!select && selection) {
setCursor(editor, Cursor.HAND_CURSOR);
}
else {
setCursor(editor, Cursor.TEXT_CURSOR);
}
}
}
public static void setCursor(final Editor view, @JdkConstants.CursorType int type) {
final Cursor cursor = type == Cursor.TEXT_CURSOR && view instanceof EditorEx ?
UIUtil.getTextCursor(((EditorEx)view).getBackgroundColor()) : Cursor.getPredefinedCursor(type);
view.getContentComponent().setCursor(cursor);
}
}
@@ -17,6 +17,7 @@
package com.intellij.application.options.colors;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptorWithPath;
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme;
import com.intellij.openapi.editor.colors.impl.ReadOnlyColorsScheme;
import com.intellij.openapi.editor.markup.EffectType;
@@ -30,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
public abstract class ColorAndFontDescription extends TextAttributes implements EditorSchemeAttributeDescriptor {
public abstract class ColorAndFontDescription extends TextAttributes implements EditorSchemeAttributeDescriptorWithPath {
private final String myName;
private final String myGroup;
private final String myType;
@@ -17,6 +17,8 @@ package com.intellij.application.options.colors;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptorWithPath;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.options.colors.AttributesDescriptor;
@@ -29,12 +31,12 @@ import com.intellij.util.BitUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.FontUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -85,7 +87,7 @@ public class ColorAndFontDescriptionPanel extends JPanel implements OptionsPanel
super(new BorderLayout());
add(myPanel, BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 4));
setBorder(JBUI.Borders.empty(4, 0, 4, 4));
myEffectsModel = new EffectsComboModel(ContainerUtil.newArrayList(myEffectsMap.keySet()));
//noinspection unchecked
myEffectsCombo.setModel(myEffectsModel);
@@ -97,12 +99,16 @@ public class ColorAndFontDescriptionPanel extends JPanel implements OptionsPanel
}
});
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
onSettingsChanged(e);
}
ActionListener actionListener = e -> {
myErrorStripeColorChooser.setEnabled(myCbErrorStripe.isSelected());
myForegroundChooser.setEnabled(myCbForeground.isSelected());
myBackgroundChooser.setEnabled(myCbBackground.isSelected());
myEffectsColorChooser.setEnabled(myCbEffects.isSelected());
myEffectsCombo.setEnabled(myCbEffects.isSelected());
myDispatcher.getMulticaster().onSettingsChanged(e);
};
for (JBCheckBox c : new JBCheckBox[]{myCbBackground, myCbForeground, myCbEffects, myCbErrorStripe, myCbItalic, myCbBold, myInheritAttributesBox}) {
c.addActionListener(actionListener);
}
@@ -110,14 +116,10 @@ public class ColorAndFontDescriptionPanel extends JPanel implements OptionsPanel
c.addActionListener(actionListener);
}
myEffectsCombo.addActionListener(actionListener);
Messages.configureMessagePaneUi(myInheritanceLabel, "<html>", null);
myInheritanceLabel.addHyperlinkListener(new HyperlinkAdapter() {
@Override
protected void hyperlinkActivated(HyperlinkEvent e) {
onHyperLinkClicked(e);
}
});
myInheritanceLabel.setBorder(BorderFactory.createEmptyBorder());
myInheritanceLabel.addHyperlinkListener(e -> myDispatcher.getMulticaster().onHyperLinkClicked(e));
myInheritanceLabel.setBorder(JBUI.Borders.empty(4, 0, 4, 4));
myLabelFont.setVisible(false); // hide for now as it doesn't look that good
}
@@ -127,20 +129,6 @@ public class ColorAndFontDescriptionPanel extends JPanel implements OptionsPanel
return this;
}
private void onHyperLinkClicked(HyperlinkEvent e) {
myDispatcher.getMulticaster().onHyperLinkClicked(e);
}
private void onSettingsChanged(ActionEvent e) {
myErrorStripeColorChooser.setEnabled(myCbErrorStripe.isSelected());
myForegroundChooser.setEnabled(myCbForeground.isSelected());
myBackgroundChooser.setEnabled(myCbBackground.isSelected());
myEffectsColorChooser.setEnabled(myCbEffects.isSelected());
myEffectsCombo.setEnabled(myCbEffects.isSelected());
myDispatcher.getMulticaster().onSettingsChanged(e);
}
public void resetDefault() {
myLabelFont.setEnabled(false);
myCbBold.setSelected(false);
@@ -172,7 +160,10 @@ public class ColorAndFontDescriptionPanel extends JPanel implements OptionsPanel
colorPanel.setEnabled(isChecked);
}
public void reset(@NotNull ColorAndFontDescription description) {
public void reset(@NotNull EditorSchemeAttributeDescriptor attrDescription) {
if (!(attrDescription instanceof ColorAndFontDescription)) return;
ColorAndFontDescription description = (ColorAndFontDescription)attrDescription;
if (description.isFontEnabled()) {
myLabelFont.setEnabled(description.isEditable());
myCbBold.setEnabled(description.isEditable());
@@ -218,7 +209,7 @@ public class ColorAndFontDescriptionPanel extends JPanel implements OptionsPanel
Pair<ColorSettingsPage, AttributesDescriptor> baseDescriptor = description.getBaseAttributeDescriptor();
if (baseDescriptor != null && baseDescriptor.second.getDisplayName() != null) {
String attrName = baseDescriptor.second.getDisplayName();
String attrLabel = attrName.replaceAll(ColorOptionsTree.NAME_SEPARATOR, FontUtil.rightArrow(UIUtil.getLabelFont()));
String attrLabel = attrName.replaceAll(EditorSchemeAttributeDescriptorWithPath.NAME_SEPARATOR, FontUtil.rightArrow(UIUtil.getLabelFont()));
ColorSettingsPage settingsPage = baseDescriptor.first;
String style = "<div style=\"text-align:right\" vertical-align=\"top\">";
String tooltipText;
@@ -263,7 +254,10 @@ public class ColorAndFontDescriptionPanel extends JPanel implements OptionsPanel
myBackgroundChooser.setEditable(isEditEnabled);
}
public void apply(@NotNull ColorAndFontDescription description, EditorColorsScheme scheme) {
public void apply(@NotNull EditorSchemeAttributeDescriptor attrDescription, EditorColorsScheme scheme) {
if (!(attrDescription instanceof ColorAndFontDescription)) return;
ColorAndFontDescription description = (ColorAndFontDescription)attrDescription;
description.setInherited(myInheritAttributesBox.isSelected());
if (description.isInherited()) {
TextAttributes baseAttributes = description.getBaseAttributes();
@@ -27,18 +27,12 @@ import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.editor.colors.ColorKey;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.colors.*;
import com.intellij.openapi.editor.colors.impl.*;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SchemeManager;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.colors.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
@@ -58,6 +52,7 @@ import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.psi.search.scope.packageSet.PackageSet;
import com.intellij.ui.ColorUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -77,6 +72,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
private Map<String, MyColorScheme> mySchemes;
private MyColorScheme mySelectedScheme;
public static final String FILE_STATUS_GROUP = ApplicationBundle.message("title.file.status");
public static final String SCOPES_GROUP = ApplicationBundle.message("title.scope.based");
@@ -94,6 +90,16 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
private boolean myDisposeCompleted = false;
private final Disposable myDisposable = Disposer.newDisposable();
private final EventDispatcher<ColorAndFontSettingsListener> myDispatcher = EventDispatcher.create(ColorAndFontSettingsListener.class);
public void addListener(@NotNull ColorAndFontSettingsListener listener) {
myDispatcher.addListener(listener);
}
public void stateChanged() {
myDispatcher.getMulticaster().settingsChanged();
}
@Override
public boolean isModified() {
boolean listModified = isSchemeListModified();
@@ -106,7 +112,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
return listModified;
}
private boolean isSchemeListModified(){
private boolean isSchemeListModified() {
if (mySomeSchemesDeleted) return true;
if (!mySelectedScheme.getName().equals(EditorColorsManager.getInstance().getGlobalScheme().getName())) return true;
@@ -508,7 +514,8 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
scheme.setDescriptors(descriptions.toArray(new EditorSchemeAttributeDescriptor[descriptions.size()]));
}
private static void initPluggedDescriptions(@NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
private static void initPluggedDescriptions(@NotNull List<EditorSchemeAttributeDescriptor> descriptions,
@NotNull MyColorScheme scheme) {
ColorSettingsPage[] pages = ColorSettingsPages.getInstance().getRegisteredPages();
for (ColorSettingsPage page : pages) {
initDescriptions(page, descriptions, scheme);
@@ -523,8 +530,27 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
@NotNull MyColorScheme scheme) {
String group = provider.getDisplayName();
List<AttributesDescriptor> attributeDescriptors = ColorSettingsUtil.getAllAttributeDescriptors(provider);
//todo: single point configuration?
if (provider instanceof RainbowColorSettingsPage) {
descriptions.add(new RainbowAttributeDescriptor(((RainbowColorSettingsPage)provider).getLanguage(),
group,
ApplicationBundle.message("rainbow.option.panel.display.name"),
scheme,
scheme.myRainbowState));
}
for (AttributesDescriptor descriptor : attributeDescriptors) {
addSchemedDescription(descriptions, descriptor.getDisplayName(), group, descriptor.getKey(), scheme, null, null);
// if (provider instanceof RainbowColorSettingsPage
// && ((RainbowColorSettingsPage)provider).isRainbowType(descriptor.getKey())) {
// //todo: joined sub-descriptor?
// descriptions.add(new RainbowAttributeDescriptor(group,
// descriptor.getDisplayName()
// + EditorSchemeAttributeDescriptorWithPath.NAME_SEPARATOR
// + ApplicationBundle.message("rainbow.option.panel.display.name"),
// scheme,
// scheme.getInitRainbowState(),
// scheme.getCurrentRainbowState()));
// }
}
ColorDescriptor[] colorDescriptors = provider.getColorDescriptors();
@@ -984,6 +1010,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
private EditorSchemeAttributeDescriptor[] myDescriptors;
private String myName;
private boolean myIsNew = false;
private RainbowColorsInSchemeState myRainbowState;
private MyColorScheme(@NotNull EditorColorsScheme parentScheme) {
super(parentScheme);
@@ -996,6 +1023,11 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
setQuickDocFontSize(parentScheme.getQuickDocFontSize());
myName = parentScheme.getName();
//noinspection UseOfPropertiesAsHashtable
getMetaProperties().putAll(parentScheme.getMetaProperties());
myRainbowState = new RainbowColorsInSchemeState(this, parentScheme);
initFonts();
}
@@ -15,6 +15,8 @@
*/
package com.intellij.application.options.colors;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptorWithPath;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.treeStructure.Tree;
@@ -26,6 +28,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.tree.*;
import java.util.*;
import static com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptorWithPath.NAME_SEPARATOR;
/**
* @author Rustam Vishnyakov
*/
@@ -33,8 +37,6 @@ public class ColorOptionsTree extends Tree {
private final String myCategoryName;
private final DefaultTreeModel myTreeModel;
public final static String NAME_SEPARATOR = "//";
private static final Comparator<EditorSchemeAttributeDescriptor> ATTR_COMPARATOR =
(o1, o2) -> StringUtil.naturalCompare(o1.toString(), o2.toString());
@@ -78,9 +80,9 @@ public class ColorOptionsTree extends Tree {
}
@Nullable
public ColorAndFontDescription getSelectedDescriptor() {
public EditorSchemeAttributeDescriptor getSelectedDescriptor() {
Object selectedValue = getSelectedValue();
return selectedValue instanceof ColorAndFontDescription ? (ColorAndFontDescription)selectedValue : null;
return selectedValue instanceof EditorSchemeAttributeDescriptor ? (EditorSchemeAttributeDescriptor)selectedValue : null;
}
@Nullable
@@ -138,7 +140,7 @@ public class ColorOptionsTree extends Tree {
@Nullable
private static List<String> extractPath(@NotNull EditorSchemeAttributeDescriptor descriptor) {
if (descriptor instanceof ColorAndFontDescription) {
if (descriptor instanceof EditorSchemeAttributeDescriptorWithPath) {
String name = descriptor.toString();
List<String> path = new ArrayList<>();
int separatorStart = name.indexOf(NAME_SEPARATOR);
@@ -72,10 +72,6 @@ public class ColorSettingsUtil {
return true;
}
static boolean isSharedScheme(EditorColorsScheme selected) {
return false;
}
private static void addInspectionSeverityAttributes(List<AttributesDescriptor> descriptors) {
descriptors.add(new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.unknown.symbol"), CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES));
descriptors.add(new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.deprecated.symbol"), CodeInsightColors.DEPRECATED_ATTRIBUTES));
@@ -0,0 +1,154 @@
/*
* Copyright 2000-2016 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.application.options.colors;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.openapi.options.colors.RainbowColorSettingsPage;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
class CustomizedSwitcherPanel extends JPanel implements OptionsPanelImpl.ColorDescriptionPanel {
private ColorSettingsPage myPage;
private PreviewPanel myPreviewPanel;
private ColorAndFontDescriptionPanel myColorAndFontPanel;
private RainbowDescriptionPanel myRainbowPanel;
private OptionsPanelImpl.ColorDescriptionPanel myActive;
public CustomizedSwitcherPanel(@Nullable PreviewPanel previewPanel,
@Nullable ColorSettingsPage page) {
super();
myPage = page;
myPreviewPanel = previewPanel;
myRainbowPanel = new RainbowDescriptionPanel();
myColorAndFontPanel = new ColorAndFontDescriptionPanel();
Dimension sizeR = myRainbowPanel.getPreferredSize();
Dimension sizeC = myColorAndFontPanel.getPreferredSize();
Dimension preferredSize = new Dimension();
preferredSize.setSize(Math.max(sizeR.getWidth(), sizeC.getWidth()),
Math.max(sizeR.getHeight(), sizeC.getHeight()));
setPreferredSize(preferredSize);
}
@NotNull
@Override
public JComponent getPanel() {
return this;
}
@Override
public void resetDefault() {
if (myActive != null) {
final PaintLocker locker = new PaintLocker(this);
try {
setPreferredSize(getSize());// froze [this] size
remove(myActive.getPanel());
myActive = null;
}
finally {
locker.release();
}
}
}
@Override
public void reset(@NotNull EditorSchemeAttributeDescriptor descriptor) {
JComponent oldPanel = myActive == null ? null : myActive.getPanel();
myActive = getPanelForDescriptor(descriptor);
JComponent newPanel = myActive == null ? null : myActive.getPanel();
if (oldPanel != newPanel) {
final PaintLocker locker = new PaintLocker(this);
try {
if (oldPanel != null) {
remove(oldPanel);
}
if (newPanel != null) {
setPreferredSize(null);// make [this] resizable
add(newPanel);
}
}
finally {
locker.release();
}
}
if (myActive != null) {
myActive.reset(descriptor);
}
updatePreviewPanel(descriptor);
}
protected OptionsPanelImpl.ColorDescriptionPanel getPanelForDescriptor(@NotNull EditorSchemeAttributeDescriptor descriptor) {
if (descriptor instanceof RainbowAttributeDescriptor) {
return myRainbowPanel;
}
else if (descriptor instanceof ColorAndFontDescription) {
return myColorAndFontPanel;
}
return null;
}
@Override
public void apply(@NotNull EditorSchemeAttributeDescriptor descriptor, EditorColorsScheme scheme) {
if (myActive != null) {
myActive.apply(descriptor, scheme);
updatePreviewPanel(descriptor);
}
}
protected void updatePreviewPanel(@NotNull EditorSchemeAttributeDescriptor descriptor) {
if (!(myPreviewPanel instanceof SimpleEditorPreview && myPage instanceof RainbowColorSettingsPage)) return;
UIUtil.invokeAndWaitIfNeeded((Runnable)() -> ApplicationManager.getApplication().runWriteAction(() -> {
SimpleEditorPreview simpleEditorPreview = (SimpleEditorPreview)myPreviewPanel;
simpleEditorPreview.setupRainbow(descriptor.getScheme(), (RainbowColorSettingsPage)myPage);
simpleEditorPreview.updateView();
}));
}
@Override
public void addListener(@NotNull Listener listener) {
myRainbowPanel.addListener(listener);
myColorAndFontPanel.addListener(listener);
}
private static class PaintLocker {
private Container myPaintHolder;
private boolean myPaintState;
public PaintLocker(@NotNull JComponent component) {
myPaintHolder = component.getParent();
myPaintState = myPaintHolder.getIgnoreRepaint();
myPaintHolder.setIgnoreRepaint(true);
}
public void release() {
myPaintHolder.validate();
myPaintHolder.setIgnoreRepaint(myPaintState);
myPaintHolder.repaint();
}
}
}
@@ -325,7 +325,7 @@ public class FontOptions extends JPanel implements OptionsPanel{
public boolean updateDescription(boolean modified) {
EditorColorsScheme scheme = myOptions.getSelectedScheme();
if (modified && (ColorAndFontOptions.isReadOnly(scheme) || ColorSettingsUtil.isSharedScheme(scheme))) {
if (modified && ColorAndFontOptions.isReadOnly(scheme)) {
return false;
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.GuiUtils;
import org.jetbrains.annotations.NotNull;
@@ -100,10 +101,8 @@ public class NewColorAndFontPanel extends JPanel {
optionsPanel.addListener(new ColorAndFontSettingsListener.Abstract() {
@Override
public void settingsChanged() {
if (schemesPanel.updateDescription(true)) {
optionsPanel.applyChangesToScheme();
previewPanel.updateView();
}
optionsPanel.applyChangesToScheme();
previewPanel.updateView();
}
@Override
@@ -133,8 +132,9 @@ public class NewColorAndFontPanel extends JPanel {
Collection<String> optionList, ColorSettingsPage page) {
final SchemesPanel schemesPanel = new SchemesPanel(options);
final OptionsPanel optionsPanel = new OptionsPanelImpl(options, schemesPanel, category);
final OptionsPanel optionsPanel = new OptionsPanelImpl(
options, schemesPanel, category,
new CustomizedSwitcherPanel(previewPanel, page));
return new NewColorAndFontPanel(schemesPanel, optionsPanel, previewPanel, category, optionList, page);
}
@@ -148,13 +148,7 @@ public class NewColorAndFontPanel extends JPanel {
if (myOptionList == null) {
return myOptionsPanel.processListOptions();
}
else {
final HashSet<String> result = new HashSet<>();
for (String s : myOptionList) {
result.add(s);
}
return result;
}
return new HashSet<>(myOptionList);
}
@@ -20,11 +20,11 @@ import com.intellij.ide.DataManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.options.ex.Settings;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -74,6 +74,7 @@ public class OptionsPanelImpl extends JPanel implements OptionsPanel {
@Override
public void onSettingsChanged(ActionEvent e) {
myDispatcher.getMulticaster().settingsChanged();
myOptions.stateChanged();
}
@Override
@@ -99,6 +100,17 @@ public class OptionsPanelImpl extends JPanel implements OptionsPanel {
}
});
myOptions.addListener(new ColorAndFontSettingsListener.Abstract() {
@Override
public void settingsChanged() {
if (!mySchemesProvider.areSchemesLoaded()) return;
if (myOptionsTree.getSelectedValue() != null) {
// update options & preview after global state change
processListValueChanged();
}
}
});
myOptionsTree = new ColorOptionsTree(myCategoryName);
myOptionsTree.addTreeSelectionListener(new TreeSelectionListener() {
@@ -122,7 +134,9 @@ public class OptionsPanelImpl extends JPanel implements OptionsPanel {
private void processListValueChanged() {
Object selectedValue = myOptionsTree.getSelectedValue();
ColorAndFontDescription description = selectedValue instanceof ColorAndFontDescription ? (ColorAndFontDescription)selectedValue : null;
EditorSchemeAttributeDescriptor description = selectedValue instanceof EditorSchemeAttributeDescriptor
? (EditorSchemeAttributeDescriptor)selectedValue
: null;
if (description == null) {
if (selectedValue == null) {
String preselectedType = myProperties.getValue(SELECTED_COLOR_OPTION_PROPERTY);
@@ -164,7 +178,7 @@ public class OptionsPanelImpl extends JPanel implements OptionsPanel {
@Override
public void applyChangesToScheme() {
ColorAndFontDescription descriptor = myOptionsTree.getSelectedDescriptor();
EditorSchemeAttributeDescriptor descriptor = myOptionsTree.getSelectedDescriptor();
if (descriptor != null) {
myOptionsPanel.apply(descriptor, myOptions.getSelectedScheme());
}
@@ -193,9 +207,9 @@ public class OptionsPanelImpl extends JPanel implements OptionsPanel {
void resetDefault();
void reset(@NotNull ColorAndFontDescription description);
void reset(@NotNull EditorSchemeAttributeDescriptor description);
void apply(@NotNull ColorAndFontDescription descriptor, EditorColorsScheme scheme);
void apply(@NotNull EditorSchemeAttributeDescriptor descriptor, EditorColorsScheme scheme);
void addListener(@NotNull Listener listener);
@@ -0,0 +1,80 @@
/*
* Copyright 2000-2016 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.application.options.colors;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptorWithPath;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
class RainbowAttributeDescriptor implements EditorSchemeAttributeDescriptorWithPath {
private final String myGroup;
private final String myDisplayName;
private final EditorColorsScheme myScheme;
private final Language myLanguage;
private final RainbowColorsInSchemeState myRainbowColorsInSchemaState;
public RainbowAttributeDescriptor(@Nullable Language language,
@NotNull String group,
@NotNull String displayNameWithPath,
@NotNull EditorColorsScheme scheme,
@NotNull RainbowColorsInSchemeState rainbowState) {
myLanguage = language;
myDisplayName = displayNameWithPath;
myRainbowColorsInSchemaState = rainbowState;
myScheme = scheme;
myGroup = group;
}
@Override
public String toString() {
return myDisplayName;
}
@Override
public String getGroup() {
return myGroup;
}
@Override
public String getType() {
return RainbowHighlighter.RAINBOW_TYPE;
}
@Override
public EditorColorsScheme getScheme() {
return myScheme;
}
@Override
public void apply(@NotNull EditorColorsScheme scheme) {
if (myLanguage == null) {
// call it once for 'Default Language'
myRainbowColorsInSchemaState.apply(scheme);
}
}
@Override
public boolean isModified() {
return myRainbowColorsInSchemaState.isModified(myLanguage);
}
public Language getLanguage() {
return myLanguage;
}
}
@@ -0,0 +1,84 @@
/*
* Copyright 2000-2016 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.application.options.colors;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
public class RainbowColorsInSchemeState {
private final EditorColorsScheme myEditedScheme;
private final EditorColorsScheme myOriginalScheme;
public RainbowColorsInSchemeState(@NotNull EditorColorsScheme editedScheme,
@NotNull EditorColorsScheme originalScheme) {
myEditedScheme = editedScheme;
myOriginalScheme = originalScheme;
}
public void apply(@NotNull EditorColorsScheme scheme) {
if (scheme != myEditedScheme) {
scheme.getMetaProperties().clear();
//noinspection UseOfPropertiesAsHashtable
scheme.getMetaProperties().putAll(myEditedScheme.getMetaProperties());
for (TextAttributesKey key : RainbowHighlighter.RAINBOW_COLOR_KEYS) {
Color color = myEditedScheme.getAttributes(key).getForegroundColor();
if (!color.equals(scheme.getAttributes(key).getForegroundColor()) ) {
scheme.setAttributes(key, RainbowHighlighter.createRainbowAttribute(color));
}
}
updateRainbowMarkup();
}
}
private static void updateRainbowMarkup() {
Editor[] allEditors = EditorFactory.getInstance().getAllEditors();
for (Editor editor : allEditors) {
final Project project = editor.getProject();
if (project != null) {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
if (file != null) {
DaemonCodeAnalyzer.getInstance(project).restart(file);
}
}
}
}
public boolean isModified(@Nullable Language language) {
return (language == null && isRainbowColorsModified())
|| RainbowHighlighter.isRainbowEnabled(myEditedScheme, language) != RainbowHighlighter.isRainbowEnabled(myOriginalScheme, language);
}
private boolean isRainbowColorsModified() {
for (TextAttributesKey key : RainbowHighlighter.RAINBOW_COLOR_KEYS) {
if (!myEditedScheme.getAttributes(key).equals(myOriginalScheme.getAttributes(key)) ) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.colors.RainbowDescriptionPanel">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="9" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="10" bottom="10" right="10"/>
<constraints>
<xy x="20" y="20" width="378" height="417"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="fcf61" class="com.intellij.ui.components.JBCheckBox" binding="myRainbow">
<constraints>
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.rainbow"/>
</properties>
</component>
<component id="5556e" class="javax.swing.JTextPane" binding="myGradientLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="label.override.gradient"/>
</properties>
</component>
<vspacer id="1f6f2">
<constraints>
<grid row="8" column="1" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="11363" class="com.intellij.ui.ColorPanel" binding="myStop1">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="a303b" class="com.intellij.ui.ColorPanel" binding="myStop2">
<constraints>
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="1c10d" class="com.intellij.ui.ColorPanel" binding="myStop3">
<constraints>
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="8db13" class="com.intellij.ui.ColorPanel" binding="myStop4">
<constraints>
<grid row="5" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="1b18c" class="com.intellij.ui.ColorPanel" binding="myStop5">
<constraints>
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<hspacer id="13e59">
<constraints>
<grid row="7" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<grid id="cf0d3" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="30" left="0" bottom="0" right="0"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="cf61c" class="com.intellij.ui.components.JBCheckBox" binding="myInheritAttributesBox">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="label.inherit.attributes"/>
</properties>
</component>
<component id="6fbd2" class="javax.swing.JTextPane" binding="myInheritanceLabel">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="labl"/>
</properties>
</component>
</children>
</grid>
<component id="203c3" class="com.intellij.ui.components.JBLabel" binding="myLStop1">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.stop.1"/>
</properties>
</component>
<component id="bfc5c" class="com.intellij.ui.components.JBLabel" binding="myLStop2">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.stop.2"/>
</properties>
</component>
<component id="93fd3" class="com.intellij.ui.components.JBLabel" binding="myLStop3">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.stop.3"/>
</properties>
</component>
<component id="e582f" class="com.intellij.ui.components.JBLabel" binding="myLStop4">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.stop.4"/>
</properties>
</component>
<component id="89cf9" class="com.intellij.ui.components.JBLabel" binding="myLStop5">
<constraints>
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.stop.5"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -0,0 +1,180 @@
/*
* Copyright 2000-2016 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.application.options.colors;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.ColorPanel;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.EventDispatcher;
import com.intellij.util.FontUtil;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.ActionListener;
public class RainbowDescriptionPanel extends JPanel implements OptionsPanelImpl.ColorDescriptionPanel {
private final EventDispatcher<Listener> myDispatcher = EventDispatcher.create(Listener.class);
protected JPanel myPanel;
private JTextPane myGradientLabel;
private JBLabel myLStop1;
private JBLabel myLStop2;
private JBLabel myLStop3;
private JBLabel myLStop4;
private JBLabel myLStop5;
private JBLabel[] myLStops = new JBLabel[]{myLStop1, myLStop2, myLStop3, myLStop4, myLStop5};
protected ColorPanel myStop1;
protected ColorPanel myStop2;
protected ColorPanel myStop3;
protected ColorPanel myStop4;
protected ColorPanel myStop5;
private ColorPanel[] myStops = new ColorPanel[]{myStop1, myStop2, myStop3, myStop4, myStop5};
private JBCheckBox myRainbow;
private JTextPane myInheritanceLabel;
private JBCheckBox myInheritAttributesBox;
private final String myInheritedMessage;
private final String myOverrideMessage;
private final String myInheritedMessageTooltip;
public RainbowDescriptionPanel() {
super(new BorderLayout());
add(myPanel, BorderLayout.CENTER);
setBorder(JBUI.Borders.empty(4, 0, 4, 4));
ActionListener actionListener = e -> myDispatcher.getMulticaster().onSettingsChanged(e);
for (JBCheckBox c : new JBCheckBox[]{myRainbow, myInheritAttributesBox}) {
c.addActionListener(actionListener);
}
for (ColorPanel c : new ColorPanel[]{myStop1, myStop2, myStop3, myStop4, myStop5}) {
c.addActionListener(actionListener);
}
String languageDefaultPageID = OptionsBundle.message("options.language.defaults.display.name");
String rainbowOptionsID = ApplicationBundle.message("rainbow.option.panel.display.name");
myInheritedMessage = ApplicationBundle.message("label.inherited.gradient",
rainbowOptionsID,
languageDefaultPageID);
myInheritedMessageTooltip = checkRightArrow(ApplicationBundle.message("label.inherited.gradient.tooltip",
rainbowOptionsID,
languageDefaultPageID));
myOverrideMessage = ApplicationBundle.message("label.override.gradient");
HyperlinkListener listener = e -> myDispatcher.getMulticaster().onHyperLinkClicked(e);
Messages.configureMessagePaneUi(myGradientLabel, myOverrideMessage, null);
myGradientLabel.addHyperlinkListener(listener);
Messages.configureMessagePaneUi(myInheritanceLabel,
checkRightArrow(ApplicationBundle.message("label.rainbow.inheritance",
rainbowOptionsID,
rainbowOptionsID,
languageDefaultPageID)),
null);
myInheritanceLabel.setToolTipText(checkRightArrow(ApplicationBundle.message("label.rainbow.inheritance.tooltip",
rainbowOptionsID,
languageDefaultPageID)));
myInheritanceLabel.addHyperlinkListener(listener);
myInheritanceLabel.setBorder(JBUI.Borders.empty(4, 0, 4, 4));
}
@NotNull
private static String checkRightArrow(@NotNull String str) {
return str.replaceAll("->", FontUtil.rightArrow(UIUtil.getLabelFont()));
}
@NotNull
@Override
public JComponent getPanel() {
return this;
}
@Override
public void resetDefault() {
}
@Override
public void reset(@NotNull EditorSchemeAttributeDescriptor attributeDescriptor) {
if (!(attributeDescriptor instanceof RainbowAttributeDescriptor)) return;
RainbowAttributeDescriptor descriptor = (RainbowAttributeDescriptor)attributeDescriptor;
EditorColorsScheme editedColorsScheme = descriptor.getScheme();
Boolean rainbowOn = RainbowHighlighter.isRainbowEnabled(editedColorsScheme, descriptor.getLanguage());
boolean isInherited = false;
// the colors are editable only for default language
boolean isDefaultLanguage = descriptor.getLanguage() == null;
boolean isEnable = !ColorAndFontOptions.isReadOnly(editedColorsScheme);
if (rainbowOn == null) {
isInherited = true;
rainbowOn = RainbowHighlighter.isRainbowEnabled(editedColorsScheme, null);
}
myRainbow.setEnabled(isEnable && !isInherited);
myRainbow.setSelected(rainbowOn);
for (int i = 0; i < myLStops.length; ++i) {
myLStops[i].setEnabled(isEnable && isDefaultLanguage);
myStops[i].setEnabled(rainbowOn);
myStops[i].setEditable(isEnable && isDefaultLanguage);
myStops[i].setSelectedColor(editedColorsScheme.getAttributes(RainbowHighlighter.RAINBOW_COLOR_KEYS[i]).getForegroundColor());
}
myInheritanceLabel.setVisible(!isDefaultLanguage);
myInheritAttributesBox.setEnabled(isEnable);
myInheritAttributesBox.setSelected(isInherited);
myInheritAttributesBox.setVisible(!isDefaultLanguage);
myGradientLabel.setText(isDefaultLanguage ? myOverrideMessage : myInheritedMessage);
myGradientLabel.setToolTipText(isDefaultLanguage ? null : myInheritedMessageTooltip);
}
@Override
public void apply(@NotNull EditorSchemeAttributeDescriptor attributeDescriptor, EditorColorsScheme scheme) {
if (!(attributeDescriptor instanceof RainbowAttributeDescriptor)) return;
RainbowAttributeDescriptor descriptor = (RainbowAttributeDescriptor)attributeDescriptor;
boolean isDefaultLanguage = descriptor.getLanguage() == null;
RainbowHighlighter.setRainbowEnabled(scheme,
descriptor.getLanguage(),
isDefaultLanguage ? Boolean.valueOf(myRainbow.isSelected())
: myInheritAttributesBox.isSelected() ? null
: Boolean.valueOf(myRainbow.isSelected()));
for (int i = 0; i < myStops.length; ++i) {
scheme.setAttributes(RainbowHighlighter.RAINBOW_COLOR_KEYS[i], RainbowHighlighter.createRainbowAttribute(myStops[i].getSelectedColor()));
}
descriptor.apply(scheme);
}
@Override
public void addListener(@NotNull Listener listener) {
myDispatcher.addListener(listener);
}
}
@@ -172,14 +172,11 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
}
}
private void changeToScheme() {
updateDescription(false);
}
@Deprecated
public boolean updateDescription(boolean modified) {
EditorColorsScheme scheme = myOptions.getSelectedScheme();
if (modified && (ColorAndFontOptions.isReadOnly(scheme) || ColorSettingsUtil.isSharedScheme(scheme))) {
if (modified && ColorAndFontOptions.isReadOnly(scheme)) {
return false;
}
@@ -201,8 +198,6 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
mySchemeComboBox.setSelectedItem(selectedSchemeBackup);
setListLoaded(true);
changeToScheme();
myDispatcher.getMulticaster().schemeChanged(this);
}
}
@@ -18,46 +18,53 @@ package com.intellij.application.options.colors;
import com.intellij.application.options.colors.highlighting.HighlightData;
import com.intellij.application.options.colors.highlighting.HighlightsExtractor;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.codeInsight.daemon.UsedColors;
import com.intellij.ide.highlighter.HighlighterFactory;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.openapi.options.colors.EditorHighlightingProvidingColorSettingsPage;
import com.intellij.openapi.options.colors.RainbowColorSettingsPage;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.Alarm;
import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class SimpleEditorPreview implements PreviewPanel{
public class SimpleEditorPreview implements PreviewPanel {
private final ColorSettingsPage myPage;
private final EditorEx myEditor;
private final Alarm myBlinkingAlarm;
private final HighlightData[] myHighlightData;
private final List<HighlightData> myHighlightData = new ArrayList<>();
private final ColorAndFontOptions myOptions;
private final EventDispatcher<ColorAndFontSettingsListener> myDispatcher = EventDispatcher.create(ColorAndFontSettingsListener.class);
private final HighlightsExtractor myHighlightsExtractor;
public SimpleEditorPreview(final ColorAndFontOptions options, final ColorSettingsPage page) {
this(options, page, true);
@@ -67,27 +74,27 @@ public class SimpleEditorPreview implements PreviewPanel{
myOptions = options;
myPage = page;
String text = page.getDemoText();
HighlightsExtractor extractant2 = new HighlightsExtractor(page.getAdditionalHighlightingTagToDescriptorMap());
List<HighlightData> highlights = new ArrayList<>();
String stripped = extractant2.extractHighlights(text, highlights);
myHighlightData = highlights.toArray(new HighlightData[highlights.size()]);
int selectedLine = -1;
myEditor = (EditorEx)FontEditorPreview.createPreviewEditor(stripped, 10, 3, selectedLine, myOptions, false);
myHighlightsExtractor = new HighlightsExtractor(page.getAdditionalHighlightingTagToDescriptorMap());
myEditor = (EditorEx)FontEditorPreview.createPreviewEditor(
myHighlightsExtractor.extractHighlights(page.getDemoText(), myHighlightData), // text without tags
10, 3, -1, myOptions, false);
FontEditorPreview.installTrafficLights(myEditor);
myBlinkingAlarm = new Alarm().setActivationComponent(myEditor.getComponent());
if (navigatable) {
addMouseMotionListener(myEditor, page.getHighlighter(), myHighlightData, false);
myEditor.getContentComponent().addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
navigate(false, myEditor.xyToLogicalPosition(new Point(e.getX(), e.getY())));
}
});
CaretListener listener = new CaretAdapter() {
myEditor.getCaretModel().addCaretListener(new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
navigate(myEditor, true, e.getNewPosition(), page.getHighlighter(), myHighlightData, false);
navigate(true, e.getNewPosition());
}
};
myEditor.getCaretModel().addCaretListener(listener);
});
}
}
@@ -95,61 +102,62 @@ public class SimpleEditorPreview implements PreviewPanel{
return myEditor;
}
private void addMouseMotionListener(final Editor view,
final SyntaxHighlighter highlighter,
final HighlightData[] data, final boolean isBackgroundImportant) {
view.getContentComponent().addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
LogicalPosition pos = view.xyToLogicalPosition(new Point(e.getX(), e.getY()));
navigate(view, false, pos, highlighter, data, isBackgroundImportant);
}
});
public void setDemoText(final String text) {
myEditor.getSelectionModel().removeSelection();
myHighlightData.clear();
myEditor.getDocument().setText(myHighlightsExtractor.extractHighlights(text, myHighlightData));
}
private void navigate(final Editor editor, boolean select,
LogicalPosition pos,
final SyntaxHighlighter highlighter,
final HighlightData[] data, final boolean isBackgroundImportant) {
int offset = editor.logicalPositionToOffset(pos);
private void navigate(boolean select, @NotNull final LogicalPosition pos) {
int offset = myEditor.logicalPositionToOffset(pos);
final SyntaxHighlighter highlighter = myPage.getHighlighter();
if (!isBackgroundImportant && editor.offsetToLogicalPosition(offset).column != pos.column) {
if (!select) {
ClickNavigator.setCursor(editor, Cursor.TEXT_CURSOR);
return;
}
String type = null;
HighlightData highlightData = getDataFromOffset(offset);
if (highlightData != null) {
// tag-based navigation first
type = RainbowHighlighter.isRainbowTempKey(highlightData.getHighlightKey())
? RainbowHighlighter.RAINBOW_TYPE
: highlightData.getHighlightType();
}
else {
// if failed, try the highlighter-based navigation
type = selectItem(((EditorEx)myEditor).getHighlighter().createIterator(offset), highlighter);
}
if (data != null) {
for (HighlightData highlightData : data) {
if (ClickNavigator.highlightDataContainsOffset(highlightData, editor.logicalPositionToOffset(pos))) {
if (!select) {
ClickNavigator.setCursor(editor, Cursor.HAND_CURSOR);
}
else {
myDispatcher.getMulticaster().selectionInPreviewChanged(highlightData.getHighlightType());
}
return;
}
}
}
setCursor(type == null ? Cursor.TEXT_CURSOR : Cursor.HAND_CURSOR);
if (highlighter != null) {
HighlighterIterator itr = ((EditorEx)editor).getHighlighter().createIterator(offset);
selectItem(itr, highlighter, select);
ClickNavigator.setCursor(editor, select ? Cursor.TEXT_CURSOR : Cursor.HAND_CURSOR);
}
}
private void selectItem(HighlighterIterator itr, SyntaxHighlighter highlighter, final boolean select) {
IElementType tokenType = itr.getTokenType();
if (tokenType == null) return;
String type = ClickNavigator.highlightingTypeFromTokenType(tokenType, highlighter);
if (select) {
if (select && type != null) {
myDispatcher.getMulticaster().selectionInPreviewChanged(type);
}
}
@Nullable
private HighlightData getDataFromOffset(int offset) {
for (HighlightData highlightData : myHighlightData) {
if (offset >= highlightData.getStartOffset() && offset <= highlightData.getEndOffset()) {
return highlightData;
}
}
return null;
}
@Nullable
private static String selectItem(HighlighterIterator itr, SyntaxHighlighter highlighter) {
IElementType tokenType = itr.getTokenType();
if (tokenType == null) return null;
TextAttributesKey[] highlights = highlighter.getTokenHighlights(tokenType);
String s = null;
for (int i = highlights.length - 1; i >= 0; i--) {
if (highlights[i] != HighlighterColors.TEXT) {
s = highlights[i].getExternalName();
break;
}
}
return s == null ? HighlighterColors.TEXT.getExternalName() : s;
}
@Override
public JComponent getPanel() {
return myEditor.getComponent();
@@ -174,16 +182,14 @@ public class SimpleEditorPreview implements PreviewPanel{
updateHighlighters();
myEditor.reinitSettings();
}
private void updateHighlighters() {
UIUtil.invokeLaterIfNeeded(() -> {
if (myEditor.isDisposed()) return;
myEditor.getMarkupModel().removeAllHighlighters();
HighlightData[] datum = myHighlightData;
final Map<TextAttributesKey, String> displayText = ColorSettingsUtil.keyToDisplayTextMap(myPage);
for (final HighlightData data : datum) {
for (final HighlightData data : myHighlightData) {
data.addHighlToView(myEditor, myOptions.getSelectedScheme(), displayText);
}
});
@@ -193,46 +199,48 @@ public class SimpleEditorPreview implements PreviewPanel{
@Override
public void blinkSelectedHighlightType(Object description) {
if (description instanceof EditorSchemeAttributeDescriptor){
if (description instanceof EditorSchemeAttributeDescriptor) {
String type = ((EditorSchemeAttributeDescriptor)description).getType();
List<HighlightData> highlights = startBlinkingHighlights(myEditor,
myHighlightData, type,
type,
myPage.getHighlighter(), true,
myBlinkingAlarm, BLINK_COUNT, myPage);
scrollHighlightInView(highlights, myEditor);
scrollHighlightInView(highlights);
}
}
private static void scrollHighlightInView(final List<HighlightData> highlightDatas, final Editor editor) {
void scrollHighlightInView(@Nullable final List<HighlightData> highlightDatas) {
if (highlightDatas == null) return;
boolean needScroll = true;
int minOffset = Integer.MAX_VALUE;
for(HighlightData data: highlightDatas) {
if (isOffsetVisible(editor, data.getStartOffset())) {
for (HighlightData data : highlightDatas) {
if (isOffsetVisible(data.getStartOffset())) {
needScroll = false;
break;
}
minOffset = Math.min(minOffset, data.getStartOffset());
}
if (needScroll && minOffset != Integer.MAX_VALUE) {
LogicalPosition pos = editor.offsetToLogicalPosition(minOffset);
editor.getScrollingModel().scrollTo(pos, ScrollType.MAKE_VISIBLE);
LogicalPosition pos = myEditor.offsetToLogicalPosition(minOffset);
myEditor.getScrollingModel().scrollTo(pos, ScrollType.MAKE_VISIBLE);
}
}
private static boolean isOffsetVisible(final Editor editor, final int startOffset) {
Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
Point point = editor.logicalPositionToXY(editor.offsetToLogicalPosition(startOffset));
return point.y >= visibleArea.y && point.y < (visibleArea.y + visibleArea.height);
private boolean isOffsetVisible(final int startOffset) {
return myEditor
.getScrollingModel()
.getVisibleArea()
.contains(myEditor.logicalPositionToXY(myEditor.offsetToLogicalPosition(startOffset)));
}
private void stopBlinking() {
public void stopBlinking() {
myBlinkingAlarm.cancelAllRequests();
}
private List<HighlightData> startBlinkingHighlights(final EditorEx editor,
final HighlightData[] highlightDatum,
final String attrKey,
final SyntaxHighlighter highlighter,
final boolean show,
@@ -244,14 +252,13 @@ public class SimpleEditorPreview implements PreviewPanel{
boolean found = false;
List<HighlightData> highlights = new ArrayList<>();
List<HighlightData> matchingHighlights = new ArrayList<>();
for (int i = 0; highlightDatum != null && i < highlightDatum.length; i++) {
HighlightData highlightData = highlightDatum[i];
for (HighlightData highlightData : myHighlightData) {
String type = highlightData.getHighlightType();
highlights.add(highlightData);
if (show && type.equals(attrKey)) {
highlightData =
new HighlightData(highlightData.getStartOffset(), highlightData.getEndOffset(),
CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES);
new HighlightData(highlightData.getStartOffset(), highlightData.getEndOffset(),
CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES);
highlights.add(highlightData);
matchingHighlights.add(highlightData);
found = true;
@@ -294,7 +301,7 @@ public class SimpleEditorPreview implements PreviewPanel{
}
}
alarm.cancelAllRequests();
alarm.addComponentRequest(() -> startBlinkingHighlights(editor, highlightDatum, attrKey, highlighter, !show, alarm, count - 1, page), 400);
alarm.addComponentRequest(() -> startBlinkingHighlights(editor, attrKey, highlighter, !show, alarm, count - 1, page), 400);
return matchingHighlights;
}
@@ -309,6 +316,84 @@ public class SimpleEditorPreview implements PreviewPanel{
EditorFactory editorFactory = EditorFactory.getInstance();
editorFactory.releaseEditor(myEditor);
stopBlinking();
}
private void setCursor(@JdkConstants.CursorType int type) {
final Cursor cursor = type == Cursor.TEXT_CURSOR ? UIUtil.getTextCursor(myEditor.getBackgroundColor())
: Cursor.getPredefinedCursor(type);
myEditor.getContentComponent().setCursor(cursor);
}
public void setupRainbow(@NotNull EditorColorsScheme colorsScheme, @NotNull RainbowColorSettingsPage page) {
final List<HighlightData> initialMarkup = new ArrayList<>();
myHighlightsExtractor.extractHighlights(page.getDemoText(), initialMarkup);
final List<HighlightData> rainbowMarkup = setupRainbowHighlighting(
page,
initialMarkup,
new RainbowHighlighter(colorsScheme).getRainbowTempKeys(),
RainbowHighlighter.isRainbowEnabledWithInheritance(colorsScheme, page.getLanguage()));
myHighlightData.clear();
myHighlightData.addAll(rainbowMarkup);
}
@NotNull
private List<HighlightData> setupRainbowHighlighting(@NotNull final RainbowColorSettingsPage page,
@NotNull final List<HighlightData> initialMarkup,
@NotNull final TextAttributesKey[] rainbowTempKeys,
boolean isRainbowOn) {
int colorCount = rainbowTempKeys.length;
if (colorCount == 0) {
return initialMarkup;
}
List<HighlightData> rainbowMarkup = new ArrayList<>();
int tempKeyIndex = 0;
for (HighlightData d : initialMarkup) {
final TextAttributesKey highlightKey = d.getHighlightKey();
final boolean rainbowType = page.isRainbowType(highlightKey);
final boolean rainbowDemoType = highlightKey == RainbowHighlighter.RAINBOW_GRADIENT_DEMO;
if (rainbowType || rainbowDemoType) {
final HighlightData rainbowAnchor = new HighlightData(d.getStartOffset(), d.getEndOffset(), RainbowHighlighter.RAINBOW_ANCHOR);
if (isRainbowOn) {
// rainbow on
HighlightData rainbowTemp;
if (rainbowType) {
rainbowTemp = getRainbowTemp(rainbowTempKeys, d.getStartOffset(), d.getEndOffset());
}
else {
rainbowTemp = new HighlightData(d.getStartOffset(), d.getEndOffset(), rainbowTempKeys[tempKeyIndex++ % colorCount]);
}
rainbowMarkup.add(rainbowTemp);
rainbowMarkup.add(rainbowAnchor);
rainbowMarkup.add(rainbowTemp);
}
else {
// rainbow off
if (rainbowType) {
rainbowMarkup.add(d);
rainbowMarkup.add(rainbowAnchor);
rainbowMarkup.add(d);
}
else {
rainbowMarkup.add(rainbowAnchor);
}
}
}
else if (!(RainbowHighlighter.isRainbowTempKey(highlightKey) || highlightKey == RainbowHighlighter.RAINBOW_ANCHOR)) {
// filter rainbow RAINBOW_TEMP and RAINBOW_ANCHOR
rainbowMarkup.add(d);
}
}
return rainbowMarkup;
}
@NotNull
private HighlightData getRainbowTemp(@NotNull TextAttributesKey[] rainbowTempKeys,
int startOffset, int endOffset) {
String id = myEditor.getDocument().getText(TextRange.create(startOffset, endOffset));
int index = UsedColors.getOrAddColorIndex((EditorImpl)myEditor, id, rainbowTempKeys.length);
return new HighlightData(startOffset, endOffset, rainbowTempKeys[index]);
}
}
@@ -92,4 +92,8 @@ public final class HighlightData {
public String getHighlightType() {
return myHighlightType.getExternalName();
}
public TextAttributesKey getHighlightKey() {
return myHighlightType;
}
}
@@ -21,6 +21,7 @@ import com.intellij.application.options.colors.ColorAndFontOptions;
import com.intellij.application.options.colors.OptionsPanelImpl;
import com.intellij.diff.util.TextDiffTypeFactory;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.ui.ColorPanel;
import com.intellij.ui.JBColor;
@@ -95,7 +96,10 @@ class DiffColorDescriptionPanel extends JPanel implements OptionsPanelImpl.Color
myInheritIgnoredCheckBox.setSelected(false);
}
public void reset(@NotNull ColorAndFontDescription description) {
public void reset(@NotNull EditorSchemeAttributeDescriptor attrDescription) {
if (!(attrDescription instanceof ColorAndFontDescription)) return;
ColorAndFontDescription description = (ColorAndFontDescription)attrDescription;
Color backgroundColor = getBackgroundColor(description);
Color ignoredColor = getIgnoredColor(description);
Color stripeMarkColor = getStripeMarkColor(description);
@@ -112,7 +116,10 @@ class DiffColorDescriptionPanel extends JPanel implements OptionsPanelImpl.Color
myInheritIgnoredCheckBox.setSelected(inheritIgnored);
}
public void apply(@NotNull ColorAndFontDescription description, EditorColorsScheme scheme) {
public void apply(@NotNull EditorSchemeAttributeDescriptor attrDescription, EditorColorsScheme scheme) {
if (!(attrDescription instanceof ColorAndFontDescription)) return;
ColorAndFontDescription description = (ColorAndFontDescription)attrDescription;
description.setBackgroundChecked(true);
description.setForegroundChecked(true);
description.setErrorStripeChecked(true);
@@ -15,6 +15,9 @@
*/
package com.intellij.openapi.options.colors.pages;
import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.HighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
@@ -24,7 +27,7 @@ import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.colors.AttributesDescriptor;
import com.intellij.openapi.options.colors.ColorDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.openapi.options.colors.RainbowColorSettingsPage;
import com.intellij.psi.codeStyle.DisplayPriority;
import com.intellij.psi.codeStyle.DisplayPrioritySortable;
import org.jetbrains.annotations.NonNls;
@@ -32,7 +35,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map;
/**
@@ -40,9 +42,8 @@ import java.util.Map;
*
* @author Rustam Vishnyakov
*/
public class DefaultLanguageColorsPage implements ColorSettingsPage, DisplayPrioritySortable {
@NonNls private static final Map<String, TextAttributesKey> TAG_HIGHLIGHTING_MAP = new HashMap<>();
public class DefaultLanguageColorsPage implements RainbowColorSettingsPage, DisplayPrioritySortable {
@NonNls private static final Map<String, TextAttributesKey> TAG_HIGHLIGHTING_MAP = RainbowHighlighter.createRainbowHLM();
private final static TextAttributesKey FAKE_BAD_CHAR =
TextAttributesKey.createTextAttributesKey("FAKE_BAD_CHAR", HighlighterColors.BAD_CHARACTER);
@@ -203,17 +204,22 @@ public class DefaultLanguageColorsPage implements ColorSettingsPage, DisplayPrio
"<brackets>[</brackets> Brackets <brackets>]</brackets>\n" +
"<line_comment>// Line comment</line_comment>\n" +
"<block_comment>/* Block comment */</block_comment>\n" +
"<doc_comment>/** \n" +
" * Doc comment\n" +
" * <doc_tag>@tag</doc_tag> <doc_markup><code>Markup</code></doc_markup>\n" +
" * <doc_tag>@param</doc_tag> <doc_tag_value>param_name</doc_tag_value> documentation\n" +
" */</doc_comment>\n" +
"<label>:Label</label>\n" +
"<predefined>predefined_symbol()</predefined>\n" +
"<const>CONSTANT</const>\n" +
"Global <global_var>variable</global_var>\n" +
"Function <func_decl>declaration</func_decl> (<param>parameter</param>)\n" +
" Local <local_var>variable</local_var>\n" +
"<doc_comment>/** \n" +
" * Doc comment\n" +
" * <doc_tag>@tag</doc_tag> <doc_markup><code>Markup</code></doc_markup>\n" +
" * " + ApplicationBundle.message("rainbow.option.panel.display.name") + ":\n" +
" * " + RainbowHighlighter.generatePaletteExample() + "\n" +
" * <doc_tag>@param</doc_tag> <doc_tag_value>parameter1</doc_tag_value> documentation\n" +
" * <doc_tag>@param</doc_tag> <doc_tag_value>parameter2</doc_tag_value> documentation\n" +
" * <doc_tag>@param</doc_tag> <doc_tag_value>parameter3</doc_tag_value> documentation\n" +
" * <doc_tag>@param</doc_tag> <doc_tag_value>parameter4</doc_tag_value> documentation\n" +
" */</doc_comment>\n" +
"Function <func_decl>declaration</func_decl> (<param>parameter1</param> <param>parameter2</param> <param>parameter3</param> <param>parameter4</param>)\n" +
" Local <local_var>variable1</local_var> <local_var>variable2</local_var> <local_var>variable3</local_var> <local_var>variable4</local_var>\n" +
"Function <func_call>call</func_call>()\n" +
"Interface <interface>Name</interface>\n" +
"<metadata>@Metadata</metadata>\n" +
@@ -256,4 +262,17 @@ public class DefaultLanguageColorsPage implements ColorSettingsPage, DisplayPrio
public DisplayPriority getPriority() {
return DisplayPriority.GENERAL_SETTINGS;
}
@Override
public boolean isRainbowType(TextAttributesKey type) {
return DefaultLanguageHighlighterColors.LOCAL_VARIABLE.equals(type)
|| DefaultLanguageHighlighterColors.PARAMETER.equals(type)
|| DefaultLanguageHighlighterColors.DOC_COMMENT_TAG_VALUE.equals(type);
}
@Nullable
@Override
public Language getLanguage() {
return null;
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.Properties;
/**
* User: spLeaner
@@ -197,4 +198,10 @@ public abstract class DelegateColorScheme implements EditorColorsScheme {
public void setConsoleLineSpacing(float lineSpacing) {
myDelegate.setConsoleLineSpacing(lineSpacing);
}
@NotNull
@Override
public Properties getMetaProperties() {
return myDelegate.getMetaProperties();
}
}
@@ -749,4 +749,17 @@ quarantine.dialog.message=OS marked this folder as 'quarantined', probably becau
quarantine.clean.progress=Cleaning quarantined status for {0}
quarantine.error.group=Quarantine Cleaner
quarantine.error.title=Warning
quarantine.error.message=Error cleaning quarantine status
quarantine.error.message=Error cleaning quarantine status
rainbow.option.panel.display.name=Semantic highlighting
label.override.gradient=<html>Override gradient:</html>
label.inherited.gradient=<html>Inherited from <a href="{0}">{1}</a> gradient:</html>
label.inherited.gradient.tooltip=<html>''{0}->Override gradient'' from<br>''{1}'' section</html>
checkbox.stop.1=Stop #1
checkbox.stop.2=Stop #2
checkbox.stop.3=Stop #3
checkbox.stop.4=Stop #4
checkbox.stop.5=Stop #5
checkbox.rainbow=<html>Unique color for each parameter<br>and local variable<br><font color=gray><sub>Chosen from generated gradient</sub></font></html>
label.rainbow.inheritance=<html><div style="text-align:right" vertical-align="top">''{0}->Unique color''<br>of <a href="{1}">{2}</html>
label.rainbow.inheritance.tooltip=<html>''{0}->Unique color'' from<br>''{1}'' section</html>
@@ -1024,6 +1024,31 @@
<option name="EFFECT_TYPE" value="0"/>
</value>
</option>
<option name="RAINBOW_COLOR0">
<value>
<option name="FOREGROUND" value="9b3b6a" />
</value>
</option>
<option name="RAINBOW_COLOR1">
<value>
<option name="FOREGROUND" value="114d77" />
</value>
</option>
<option name="RAINBOW_COLOR2">
<value>
<option name="FOREGROUND" value="bc8650" />
</value>
</option>
<option name="RAINBOW_COLOR3">
<value>
<option name="FOREGROUND" value="005910" />
</value>
</option>
<option name="RAINBOW_COLOR4">
<value>
<option name="FOREGROUND" value="bc5150" />
</value>
</option>
</attributes>
</scheme>
@@ -2086,6 +2111,31 @@
<option name="FONT_TYPE" value="1" />
</value>
</option>
<option name="RAINBOW_COLOR0">
<value>
<option name="FOREGROUND" value="529d52" />
</value>
</option>
<option name="RAINBOW_COLOR1">
<value>
<option name="FOREGROUND" value="be7070" />
</value>
</option>
<option name="RAINBOW_COLOR2">
<value>
<option name="FOREGROUND" value="3d7676" />
</value>
</option>
<option name="RAINBOW_COLOR3">
<value>
<option name="FOREGROUND" value="be9970" />
</value>
</option>
<option name="RAINBOW_COLOR4">
<value>
<option name="FOREGROUND" value="9d527c" />
</value>
</option>
</attributes>
</scheme>
@@ -67,6 +67,8 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.impl.DocumentImpl;
@@ -1738,10 +1740,10 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
public void testRainbow(@NotNull String fileName, @NotNull String text, boolean isRainbowOn, boolean withColor) {
RegistryValue registryValue = Registry.get("editor.rainbow.identifiers");
final boolean rainbowColors = registryValue.asBoolean();
final EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
final boolean isRainbowOnInScheme = RainbowHighlighter.isRainbowEnabled(globalScheme, null);
try {
registryValue.setValue(isRainbowOn);
RainbowHighlighter.setRainbowEnabled(globalScheme, null, isRainbowOn);
configureByText(fileName, text.replaceAll("<" + RAINBOW + "(\\scolor=\'[^\']*\')?>", "").replace("</" + RAINBOW + ">", ""));
Assert.assertEquals(text, getHighlightingDescription(ContainerUtil.filter(doHighlighting(),
@@ -1749,7 +1751,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
withColor));
}
finally {
registryValue.setValue(rainbowColors);
RainbowHighlighter.setRainbowEnabled(globalScheme, null, isRainbowOnInScheme);
}
}
@@ -489,6 +489,12 @@ public class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvi
public void setConsoleLineSpacing(float lineSpacing) {
getGlobal().setConsoleLineSpacing(lineSpacing);
}
@NotNull
@Override
public Properties getMetaProperties() {
return myGlobalScheme.getMetaProperties();
}
}
public void addListener(TerminalSettingsListener listener) {