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;
}
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(varType).range(elementToHighlight);
- return RainbowHighlighter.isRainbowEnabled() ? builder.createUnconditionally() : builder.create();
+ return RainbowHighlighter.isRainbowEnabledWithInheritance(JavaLanguage.INSTANCE) ? builder.createUnconditionally()
+ : builder.create();
}
@Nullable
import com.intellij.application.options.colors.InspectionColorSettingsPage;
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.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.StdFileTypes;
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),
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);
+ }
+
+ @NotNull
+ @Override
+ public String getRainbowDemoText() {
+ return
+ "import <class>java.util.Date</class>;\n" +
+ "class <class>SomeClass</class> {\n" +
+ " public int <field>field</field>;\n" +
+ " <constructorDeclaration>SomeClass</constructorDeclaration>(<interface>AnInterface</interface> <param>param</param>) {\n" +
+ "\n" +
+ " }\n" +
+ " /**\n" +
+ " * Doc comment\n" +
+ " * @param <javadocTagValue>param1</javadocTagValue> function param\n" +
+ " * @param <javadocTagValue>param2</javadocTagValue>\n" +
+ " * @param <javadocTagValue>param3</javadocTagValue>\n" +
+ " * @param <javadocTagValue>param4</javadocTagValue>\n" +
+ " * @param <javadocTagValue>param5</javadocTagValue>\n" +
+ " */\n" +
+ " void <methodDeclaration>method</methodDeclaration>(int <param>param1</param>,\n" +
+ " int <param>param2</param>,\n" +
+ " int <param>param3</param>,\n" +
+ " int <param>param4</param>,\n" +
+ " int <param>param5</param>) {\n" +
+ " int <localVar>localVar1</localVar>, <localVar>localVar2</localVar>, <localVar>localVar3</localVar>, <localVar>localVar4</localVar>, <localVar>localVar5</localVar>;\n" +
+ "\n" +
+ " <localVar>localVar3</localVar> = <param>param2</param>;\n" +
+ " this.<field>field</field> = <localVar>localVar3</localVar> + <param>param1</param> + <param>param5</param>;\n" +
+ " }\n" +
+ "}\n";
+ }
+
+ @Nullable
+ @Override
+ public Language getLanguage() {
+ return JavaLanguage.INSTANCE;
+ }
}
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.lang.Language;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesScheme;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringHash;
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;
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 String FALSE = "false";
+ private static String TRUE = "true";
+ private static String INHERITED = "inherited";
+
static {
for (int i = 0; i < RAINBOW_JB_COLORS_DEFAULT.length; ++i) {
JBColor jbColor = RAINBOW_JB_COLORS_DEFAULT[i];
RAINBOW_COLOR_KEYS[i] = TextAttributesKey.createTextAttributesKey("RAINBOW_COLOR" + i, textAttributes);
}
}
+ public final static String RAINBOW_TYPE = "rainbow";
+ private final static String RAINBOW_TEMP_PREF = "RAINBOW_TEMP_";
+ public final static Boolean DEFAULT_RAINBOW_ON = Boolean.FALSE;
@NotNull private final TextAttributesScheme myColorsScheme;
@NotNull private final Color[] myRainbowColors;
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 Language language) {
+ String value = PropertiesComponent.getInstance().getValue(getKey(language), INHERITED);
+ if (TRUE.equals(value)) return Boolean.TRUE;
+ if (FALSE.equals(value)) return Boolean.FALSE;
+ return language == null ? DEFAULT_RAINBOW_ON : null;
+ }
+
+ public static boolean isRainbowEnabledWithInheritance(@Nullable Language language) {
+ Boolean rainbowEnabled = isRainbowEnabled(language);
+ return rainbowEnabled != null ? rainbowEnabled : isRainbowEnabled(null);
+ }
+
+ public static void setRainbowEnabled(@Nullable Language language, @Nullable Boolean enabled) {
+ PropertiesComponent.getInstance().setValue(
+ getKey(language),
+ enabled == null ? INHERITED : enabled.toString());
}
@NotNull
+ private static String getKey(@Nullable Language language) {
+ return RAINBOW_TYPE + (language == null ? "Default language" : language.getID());
+ }
+
+ public static int hashColor(@NotNull String name, int colorsCount) {
+ return Math.abs(StringHash.murmur(name, 0x55AA)) % colorsCount;
+ }
+
+ public static int getColorIndex(@NotNull int[] index2usage, int hashedIndex, int colorsCount) {
+ int minIndex1 = indexOfMin(index2usage, hashedIndex, colorsCount);
+ int minIndex2 = indexOfMin(index2usage, 0, hashedIndex);
+ return index2usage[minIndex1] <= index2usage[minIndex2] ? minIndex1 : minIndex2;
+ }
+
+ @Contract(pure = true)
+ private static int indexOfMin(@NotNull int[] index2usage, int start, int end) {
+ int min = Integer.MAX_VALUE;
+ int minIndex = start;
+ for (int i = start; i < end; i++) {
+ int value = index2usage[i];
+ if (value < min) {
+ min = value;
+ minIndex = i;
+ }
+ }
+ return minIndex;
+ }
+
+ @NotNull
+ @Contract(pure = true)
private Color calculateForeground(int colorIndex) {
return myRainbowColors[colorIndex];
}
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) {
+ 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;
}
.fromFlyweight(myColorsScheme
.getAttributes(colorKey)
.getFlyweight()
- .withForeground(calculateForeground(colorIndex))))
- .range(id)
- .create();
+ .withForeground(calculateForeground(colorIndex))));
}
}
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.NotNull;
while (true) {
Object newColors;
if (data == null) {
- colorIndex = hashColor(name, colorsCount);
+ colorIndex = RainbowHighlighter.hashColor(name, colorsCount);
newColors = new UsedColor(name, colorIndex); // put an object instead of array to save space
}
else if (data instanceof UsedColor) {
newColors = null; // found, no need to create new
}
else {
- int hashedIndex = hashColor(name, colorsCount);
+ int hashedIndex = RainbowHighlighter.hashColor(name, colorsCount);
if (hashedIndex == usedColor.index) hashedIndex = (hashedIndex + 1) % colorsCount;
colorIndex = hashedIndex;
UsedColor newColor = new UsedColor(name, colorIndex);
}
else {
colorIndex = -1;
- int hashedIndex = hashColor(name, colorsCount);
+ int hashedIndex = RainbowHighlighter.hashColor(name, colorsCount);
int[] index2usage = new int[colorsCount];
UsedColor[] usedColors = (UsedColor[])data;
for (UsedColor usedColor : usedColors) {
}
}
if (colorIndex == -1) {
- int minIndex1 = indexOfMin(index2usage, hashedIndex, colorsCount);
- int minIndex2 = indexOfMin(index2usage, 0, hashedIndex);
- colorIndex = index2usage[minIndex1] <= index2usage[minIndex2] ? minIndex1 : minIndex2;
+ colorIndex = RainbowHighlighter.getColorIndex(index2usage, hashedIndex, colorsCount);
UsedColor newColor = new UsedColor(name, colorIndex);
newColors = ArrayUtil.append(usedColors, newColor);
}
return colorIndex;
}
-
- private static int hashColor(@NotNull String name, int colorsCount) {
- return Math.abs(StringHash.murmur(name, 0x55AA)) % colorsCount;
- }
-
- private static int indexOfMin(@NotNull int[] values, int start, int end) {
- int min = Integer.MAX_VALUE;
- int minIndex = start;
- for (int i = start; i < end; i++) {
- int value = values[i];
- if (value < min) {
- min = value;
- minIndex = i;
- }
- }
- return minIndex;
- }
}
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(psiFile.getLanguage())) {
continue;
}
if (visitor.suitableForFile(psiFile)) {
/*
- * 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.
* 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();
--- /dev/null
+/*
+ * 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 = "//";
+}
--- /dev/null
+/*
+ * 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.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface RainbowColorSettingsPage extends ColorSettingsPage {
+ boolean isRainbowType(TextAttributesKey type);
+
+ @NotNull
+ String getRainbowDemoText();
+
+ @Nullable
+ Language getLanguage();
+}
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptor;
import com.intellij.psi.tree.IElementType;
import com.intellij.ui.ScrollingUtil;
import com.intellij.util.ui.UIUtil;
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;
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;
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;
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;
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);
}
});
- 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);
}
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
}
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);
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());
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;
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();
--- /dev/null
+/*
+ * 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.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.util.EventDispatcher;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ColorAndFontGlobalState {
+ private final EventDispatcher<ColorAndFontSettingsListener> myDispatcher = EventDispatcher.create(ColorAndFontSettingsListener.class);
+ private HashMap<Language, Boolean> myLanguage2RainbowEnabled = new HashMap<>();
+ private final ColorAndFontGlobalState myReferenceState;
+
+ @Nullable
+ @Contract("null -> !null")
+ public Boolean isRainbowOn(@Nullable Language language) {
+ assert myReferenceState != null;
+ if (myLanguage2RainbowEnabled.containsKey(language)) {
+ return myLanguage2RainbowEnabled.get(language);
+ }
+ Boolean rainbowOn = RainbowHighlighter.isRainbowEnabled(language);
+ myReferenceState.myLanguage2RainbowEnabled.put(language, rainbowOn);
+ myLanguage2RainbowEnabled.put(language, rainbowOn);
+ return rainbowOn;
+ }
+
+ public boolean isRainbowOnWithInheritance(@Nullable Language language) {
+ Boolean value = isRainbowOn(language);
+ return value == null ? isRainbowOn(null) : value.booleanValue();
+ }
+
+ public void setRainbowOn(@Nullable Language language, @Nullable Boolean rainbowOn) {
+ assert myReferenceState != null;
+ myLanguage2RainbowEnabled.put(language, rainbowOn);
+ }
+
+ private ColorAndFontGlobalState(@SuppressWarnings("UnusedParameters") boolean unused) {
+ myReferenceState = null;
+ }
+
+ public ColorAndFontGlobalState() {
+ myReferenceState = new ColorAndFontGlobalState(true);
+ copyFrom(myReferenceState); //be ready to global data extension
+ }
+
+ private void copyFrom(@NotNull ColorAndFontGlobalState state) {
+ assert this != state;
+ myLanguage2RainbowEnabled = new HashMap<>(state.myLanguage2RainbowEnabled);
+ }
+
+ public void apply() {
+ for (Map.Entry<Language, Boolean> entry : myLanguage2RainbowEnabled.entrySet()) {
+ RainbowHighlighter.setRainbowEnabled(entry.getKey(), entry.getValue());
+ }
+ 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);
+ }
+ }
+ }
+ myReferenceState.copyFrom(this);
+ }
+
+ public void addListener(@NotNull ColorAndFontSettingsListener listener) {
+ myDispatcher.addListener(listener);
+ }
+
+ public void stateChanged() {
+ myDispatcher.getMulticaster().settingsChanged();
+ }
+
+ public boolean isModified() {
+ return !myLanguage2RainbowEnabled.equals(myReferenceState.myLanguage2RainbowEnabled);
+ }
+
+ public boolean isModified(@Nullable Language language) {
+ return myLanguage2RainbowEnabled.get(language) != myReferenceState.myLanguage2RainbowEnabled.get(language);
+ }
+
+ public void reset() {
+ copyFrom(myReferenceState);
+ }
+}
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;
private Map<String, MyColorScheme> mySchemes;
private MyColorScheme mySelectedScheme;
+
+ private final ColorAndFontGlobalState myColorAndFontGlobalState = new ColorAndFontGlobalState();
+
public static final String FILE_STATUS_GROUP = ApplicationBundle.message("title.file.status");
public static final String SCOPES_GROUP = ApplicationBundle.message("title.scope.based");
private boolean myDisposeCompleted = false;
private final Disposable myDisposable = Disposer.newDisposable();
+ public ColorAndFontGlobalState getColorAndFontGlobalState() {
+ return myColorAndFontGlobalState;
+ }
+
@Override
public boolean isModified() {
boolean listModified = isSchemeListModified();
return listModified;
}
- private boolean isSchemeListModified(){
+ private boolean isSchemeListModified() {
if (mySomeSchemesDeleted) return true;
if (!mySelectedScheme.getName().equals(EditorColorsManager.getInstance().getGlobalScheme().getName())) return true;
clone.setName(name);
MyColorScheme newScheme = new MyColorScheme(clone);
- initScheme(newScheme);
+ initScheme(myColorAndFontGlobalState, newScheme);
newScheme.setIsNew();
public void addImportedScheme(@NotNull EditorColorsScheme imported) {
MyColorScheme newScheme = new MyColorScheme(imported);
- initScheme(newScheme);
+ initScheme(myColorAndFontGlobalState, newScheme);
mySchemes.put(imported.getName(), newScheme);
selectScheme(newScheme.getName());
}
try {
+ myColorAndFontGlobalState.apply();
+
EditorColorsManager myColorsManager = EditorColorsManager.getInstance();
SchemeManager<EditorColorsScheme> schemeManager = ((EditorColorsManagerImpl)myColorsManager).getSchemeManager();
}
private void initAll() {
+ myColorAndFontGlobalState.reset();
mySchemes = new THashMap<>();
for (EditorColorsScheme allScheme : EditorColorsManager.getInstance().getAllSchemes()) {
MyColorScheme schemeDelegate = new MyColorScheme(allScheme);
- initScheme(schemeDelegate);
+ initScheme(myColorAndFontGlobalState, schemeDelegate);
mySchemes.put(schemeDelegate.getName(), schemeDelegate);
}
assert mySelectedScheme != null : EditorColorsManager.getInstance().getGlobalScheme().getName() + "; myschemes=" + mySchemes;
}
- private static void initScheme(@NotNull MyColorScheme scheme) {
+ private static void initScheme(@NotNull ColorAndFontGlobalState colorAndFontGlobalState, @NotNull MyColorScheme scheme) {
List<EditorSchemeAttributeDescriptor> descriptions = new ArrayList<>();
- initPluggedDescriptions(descriptions, scheme);
+ initPluggedDescriptions(colorAndFontGlobalState, descriptions, scheme);
initFileStatusDescriptors(descriptions, scheme);
initScopesDescriptors(descriptions, scheme);
scheme.setDescriptors(descriptions.toArray(new EditorSchemeAttributeDescriptor[descriptions.size()]));
}
- private static void initPluggedDescriptions(@NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
+ private static void initPluggedDescriptions(@NotNull ColorAndFontGlobalState colorAndFontGlobalState,
+ @NotNull List<EditorSchemeAttributeDescriptor> descriptions,
+ @NotNull MyColorScheme scheme) {
ColorSettingsPage[] pages = ColorSettingsPages.getInstance().getRegisteredPages();
for (ColorSettingsPage page : pages) {
- initDescriptions(page, descriptions, scheme);
+ initDescriptions(colorAndFontGlobalState, page, descriptions, scheme);
}
for (ColorAndFontDescriptorsProvider provider : Extensions.getExtensions(ColorAndFontDescriptorsProvider.EP_NAME)) {
- initDescriptions(provider, descriptions, scheme);
+ initDescriptions(colorAndFontGlobalState, provider, descriptions, scheme);
}
}
- private static void initDescriptions(@NotNull ColorAndFontDescriptorsProvider provider,
+ private static void initDescriptions(@NotNull ColorAndFontGlobalState colorAndFontGlobalState,
+ @NotNull ColorAndFontDescriptorsProvider provider,
@NotNull List<EditorSchemeAttributeDescriptor> descriptions,
@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(),
+ colorAndFontGlobalState,
+ group,
+ ApplicationBundle.message("rainbow.option.panel.display.name"),
+ scheme,
+ scheme.getRainbowState()));
+ }
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();
private EditorSchemeAttributeDescriptor[] myDescriptors;
private String myName;
private boolean myIsNew = false;
+ private RainbowColorsInSchemeState myRainbowState;
private MyColorScheme(@NotNull EditorColorsScheme parentScheme) {
super(parentScheme);
}
return false;
}
+
+ public RainbowColorsInSchemeState getRainbowState() {
+ if (myRainbowState == null) {
+ myRainbowState = new RainbowColorsInSchemeState(this);
+ }
+ return myRainbowState;
+ }
}
@Override
*/
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;
import javax.swing.tree.*;
import java.util.*;
+import static com.intellij.openapi.editor.colors.EditorSchemeAttributeDescriptorWithPath.NAME_SEPARATOR;
+
/**
* @author Rustam Vishnyakov
*/
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());
}
@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
@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);
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));
--- /dev/null
+/*
+ * 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.codeHighlighting.RainbowHighlighter;
+import com.intellij.openapi.application.ApplicationManager;
+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.ex.DocumentEx;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.options.colors.ColorSettingsPage;
+import com.intellij.openapi.options.colors.RainbowColorSettingsPage;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+class CustomizedSwitcherPanel extends JPanel implements OptionsPanelImpl.ColorDescriptionPanel {
+ private ColorAndFontGlobalState myColorAndFontGlobalState;
+ private ColorSettingsPage myPage;
+
+ private PreviewPanel myPreviewPanel;
+ private ColorAndFontDescriptionPanel myColorAndFontPanel;
+ private RainbowDescriptionPanel myRainbowPanel;
+
+ private OptionsPanelImpl.ColorDescriptionPanel myActive;
+
+ public CustomizedSwitcherPanel(@NotNull ColorAndFontGlobalState colorAndFontGlobalState,
+ @Nullable PreviewPanel previewPanel,
+ @Nullable ColorSettingsPage page) {
+ super();
+ myColorAndFontGlobalState = colorAndFontGlobalState;
+ 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;
+ }
+
+ private void addRainbowHighlighting(@NotNull DocumentEx document,
+ @Nullable List<HighlightData> showLineData,
+ @NotNull List<HighlightData> data,
+ @NotNull TextAttributesKey[] rainbowTempKeys) {
+ int colorCount = rainbowTempKeys.length;
+ if (colorCount != 0) {
+ List<HighlightData> newData = new ArrayList<>();
+ if (showLineData != null) newData.addAll(showLineData);
+
+ int[] index2usage = new int[colorCount];
+ for (HighlightData d : data) {
+ if (((RainbowColorSettingsPage)myPage).isRainbowType(d.getHighlightKey())) {
+ String id = document.getText(TextRange.create(d.getStartOffset(), d.getEndOffset()));
+
+ int index = RainbowHighlighter.getColorIndex(index2usage, RainbowHighlighter.hashColor(id, colorCount), colorCount);
+ ++index2usage[index];
+ HighlightData rainbow = new HighlightData(d.getStartOffset(), d.getEndOffset(), rainbowTempKeys[index]);
+
+ //fixme: twisted coloring in editor. We need add rainbow-tag twice.
+ newData.add(rainbow);
+ newData.add(d);
+ newData.add(rainbow);
+ }
+ else {
+ newData.add(d);
+ }
+ }
+ data.clear();
+ data.addAll(newData);
+ }
+ }
+
+ @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)) return;
+ UIUtil.invokeAndWaitIfNeeded((Runnable)() -> ApplicationManager.getApplication().runWriteAction(() -> {
+ SimpleEditorPreview simpleEditorPreview = (SimpleEditorPreview)myPreviewPanel;
+ try {
+ simpleEditorPreview.setNavigationBlocked(true);
+ String demoText = (myPage instanceof RainbowColorSettingsPage
+ && descriptor instanceof RainbowAttributeDescriptor)
+ ? ((RainbowColorSettingsPage)myPage).getRainbowDemoText()
+ : myPage.getDemoText();
+ List<HighlightData> showLineData = null;
+
+ if (myPage instanceof RainbowColorSettingsPage
+ && myColorAndFontGlobalState.isRainbowOnWithInheritance(((RainbowColorSettingsPage)myPage).getLanguage())) {
+ RainbowHighlighter highlighter = new RainbowHighlighter(descriptor.getScheme());
+ TextAttributesKey[] tempKeys = highlighter.getRainbowTempKeys();
+ EditorEx editor = simpleEditorPreview.getEditor();
+ if (myActive == myRainbowPanel) {
+ Pair<String, List<HighlightData>> demo = getColorDemoLine(highlighter, tempKeys);
+ simpleEditorPreview.setDemoText(demo.first + "\n" + demoText);
+ showLineData = demo.second;
+ }
+ else {
+ simpleEditorPreview.setDemoText(demoText);
+ }
+ addRainbowHighlighting(editor.getDocument(),
+ showLineData,
+ simpleEditorPreview.getHighlightDataForExtension(),
+ tempKeys);
+ }
+ else {
+ simpleEditorPreview.setDemoText(demoText);
+ }
+
+ simpleEditorPreview.updateView();
+ if (descriptor instanceof RainbowAttributeDescriptor) {
+ simpleEditorPreview.scrollHighlightInView(showLineData);
+ }
+ } finally {
+ simpleEditorPreview.setNavigationBlocked(false);
+ }
+ }));
+ }
+
+ @NotNull
+ private static Pair<String, List<HighlightData>> getColorDemoLine(RainbowHighlighter highlighter, TextAttributesKey[] tempKeys) {
+ int colorsCount = highlighter.getColorsCount();
+ int stopCount = RainbowHighlighter.RAINBOW_COLOR_KEYS.length;
+ List<HighlightData> markup = new ArrayList<>(colorsCount);
+ StringBuilder sb = new StringBuilder();
+ int pos = 0;
+ int i = 0;
+ for (TextAttributesKey key : tempKeys) {
+ String toAdd = (i % stopCount == 0) ? "Stop#" + String.valueOf(i / stopCount + 1) : "T";
+ int end = pos + toAdd.length();
+ markup.add(new HighlightData(pos, end, key));
+ if (sb.length() != 0) {
+ sb.append(" ");
+ }
+ sb.append(toAdd);
+ pos = end + 1;
+ ++i;
+ }
+ return Pair.create(sb.toString(), markup);
+ }
+
+ @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();
+ }
+ }
+}
public boolean updateDescription(boolean modified) {
EditorColorsScheme scheme = myOptions.getSelectedScheme();
- if (modified && (ColorAndFontOptions.isReadOnly(scheme) || ColorSettingsUtil.isSharedScheme(scheme))) {
+ if (modified && ColorAndFontOptions.isReadOnly(scheme)) {
return false;
}
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;
optionsPanel.addListener(new ColorAndFontSettingsListener.Abstract() {
@Override
public void settingsChanged() {
- if (schemesPanel.updateDescription(true)) {
- optionsPanel.applyChangesToScheme();
- previewPanel.updateView();
- }
+ optionsPanel.applyChangesToScheme();
+ previewPanel.updateView();
}
@Override
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(options.getColorAndFontGlobalState(), previewPanel, page));
return new NewColorAndFontPanel(schemesPanel, optionsPanel, previewPanel, category, optionList, page);
}
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.*;
@Override
public void onSettingsChanged(ActionEvent e) {
myDispatcher.getMulticaster().settingsChanged();
+ myOptions.getColorAndFontGlobalState().stateChanged();
}
@Override
}
});
+ myOptions.getColorAndFontGlobalState().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() {
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);
@Override
public void applyChangesToScheme() {
- ColorAndFontDescription descriptor = myOptionsTree.getSelectedDescriptor();
+ EditorSchemeAttributeDescriptor descriptor = myOptionsTree.getSelectedDescriptor();
if (descriptor != null) {
myOptionsPanel.apply(descriptor, myOptions.getSelectedScheme());
}
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);
--- /dev/null
+/*
+ * 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 com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+import java.util.List;
+
+class RainbowAttributeDescriptor implements EditorSchemeAttributeDescriptorWithPath {
+ private final String myGroup;
+ private final ColorAndFontGlobalState myColorAndFontGlobalState;
+ private final String myDisplayName;
+ private final EditorColorsScheme myScheme;
+ private final Language myLanguage;
+ private final RainbowColorsInSchemeState myRainbowColorsInSchemaState;
+
+ public ColorAndFontGlobalState getColorAndFontGlobalState() {
+ return myColorAndFontGlobalState;
+ }
+
+ public RainbowAttributeDescriptor(@Nullable Language language,
+ @NotNull ColorAndFontGlobalState colorAndFontGlobalState,
+ @NotNull String group,
+ @NotNull String displayNameWithPath,
+ @NotNull EditorColorsScheme scheme,
+ @NotNull RainbowColorsInSchemeState rainbowState) {
+ myLanguage = language;
+ myColorAndFontGlobalState = colorAndFontGlobalState;
+ 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) {
+ myRainbowColorsInSchemaState.apply(scheme);
+ }
+ // see myColorAndFontGlobalState apply
+ }
+
+ @Override
+ public boolean isModified() {
+ return (myLanguage == null && myRainbowColorsInSchemaState.isModified())
+ || myColorAndFontGlobalState.isModified(myLanguage);
+ }
+
+ public List<Pair<Boolean, Color>> getRainbowColorsInSchemaState() {
+ return myRainbowColorsInSchemaState.getInheritanceAndColors();
+ }
+
+ public Color getDefaultColor(int index) {
+ return RainbowHighlighter.RAINBOW_COLOR_KEYS[index].getDefaultAttributes().getForegroundColor();
+ }
+
+ public Language getLanguage() {
+ return myLanguage;
+ }
+}
--- /dev/null
+/*
+ * 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.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+public class RainbowColorsInSchemeState {
+ private final RainbowColorsInSchemeState myReferenceState;
+ private final List<Pair<Boolean, Color>> myInheritanceAndColors = new ArrayList<>();
+
+ public List<Pair<Boolean, Color>> getInheritanceAndColors() {
+ return myInheritanceAndColors;
+ }
+
+ private RainbowColorsInSchemeState(@NotNull EditorColorsScheme scheme,
+ @SuppressWarnings("UnusedParameters") boolean unused) {
+ myReferenceState = null;
+ for (TextAttributesKey rainbowKey : RainbowHighlighter.RAINBOW_COLOR_KEYS) {
+ myInheritanceAndColors.add(getColorStateFromScheme(scheme, rainbowKey));
+ }
+ }
+
+ public RainbowColorsInSchemeState(@NotNull EditorColorsScheme scheme) {
+ myReferenceState = new RainbowColorsInSchemeState(scheme, true);
+ copyFrom(myReferenceState);
+ }
+
+ private void copyFrom(@NotNull RainbowColorsInSchemeState state) {
+ assert this != state;
+ myInheritanceAndColors.clear();
+ myInheritanceAndColors.addAll(state.myInheritanceAndColors);
+ }
+
+ public void apply(@NotNull EditorColorsScheme scheme) {
+ int i = 0;
+ for (TextAttributesKey rainbowKey : RainbowHighlighter.RAINBOW_COLOR_KEYS) {
+ Pair<Boolean, Color> pair = myInheritanceAndColors.get(i);
+ scheme.setAttributes(rainbowKey, pair.first ? new TextAttributes(pair.second, null, null, null, Font.PLAIN)
+ : rainbowKey.getDefaultAttributes());
+ ++i;
+ }
+ //myReferenceState.copyFrom(this);
+ }
+
+ @NotNull
+ private static Pair<Boolean, Color> getColorStateFromScheme(@NotNull EditorColorsScheme scheme, TextAttributesKey rainbowKey) {
+ TextAttributes schemeAttributes = scheme.getAttributes(rainbowKey);
+ @NotNull Color defaultRainbow = rainbowKey.getDefaultAttributes().getForegroundColor();
+ Pair<Boolean, Color> pair;
+ if (schemeAttributes == null) {
+ pair = Pair.create(false, defaultRainbow);
+ }
+ else {
+ Color schemeColor = schemeAttributes.getForegroundColor();
+ if (schemeColor == null) {
+ pair = Pair.create(false, defaultRainbow);
+ }
+ else {
+ pair = Pair.create(!defaultRainbow.equals(schemeColor), schemeColor);
+ }
+ }
+ return pair;
+ }
+
+ public boolean isModified() {
+ return !myInheritanceAndColors.equals(myReferenceState.myInheritanceAndColors);
+ }
+}
--- /dev/null
+<?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="f26f6" class="com.intellij.ui.components.JBCheckBox" binding="myCbStop1">
+ <constraints>
+ <grid row="2" 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="checkbox.stop.1"/>
+ </properties>
+ </component>
+ <component id="e998a" class="com.intellij.ui.components.JBCheckBox" binding="myCbStop2">
+ <constraints>
+ <grid row="3" 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="checkbox.stop.2"/>
+ </properties>
+ </component>
+ <component id="f929a" class="com.intellij.ui.components.JBCheckBox" binding="myCbStop3">
+ <constraints>
+ <grid row="4" 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="checkbox.stop.3"/>
+ </properties>
+ </component>
+ <component id="6dc1" class="com.intellij.ui.components.JBCheckBox" binding="myCbStop4">
+ <constraints>
+ <grid row="5" 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="checkbox.stop.4"/>
+ </properties>
+ </component>
+ <component id="bce0f" class="com.intellij.ui.components.JBCheckBox" binding="myCbStop5">
+ <constraints>
+ <grid row="6" 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="checkbox.stop.5"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+</form>
--- /dev/null
+/*
+ * 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.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.openapi.util.Pair;
+import com.intellij.ui.ColorPanel;
+import com.intellij.ui.components.JBCheckBox;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.ui.JBUI;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.HyperlinkListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+
+public class RainbowDescriptionPanel extends JPanel implements OptionsPanelImpl.ColorDescriptionPanel {
+ private final EventDispatcher<Listener> myDispatcher = EventDispatcher.create(Listener.class);
+
+ protected JPanel myPanel;
+
+ private JTextPane myGradientLabel;
+ private JBCheckBox myCbStop1;
+ private JBCheckBox myCbStop2;
+ private JBCheckBox myCbStop3;
+ private JBCheckBox myCbStop4;
+ private JBCheckBox myCbStop5;
+ private JBCheckBox[] myCbStops = new JBCheckBox[]{myCbStop1, myCbStop2, myCbStop3, myCbStop4, myCbStop5};
+
+ 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, myCbStop1, myCbStop2, myCbStop3, myCbStop4, myCbStop5, 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 = 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, ApplicationBundle.message("label.rainbow.inheritance",
+ rainbowOptionsID,
+ rainbowOptionsID,
+ languageDefaultPageID), null);
+ myInheritanceLabel.setToolTipText(ApplicationBundle.message("label.rainbow.inheritance.tooltip",
+ rainbowOptionsID,
+ languageDefaultPageID));
+ myInheritanceLabel.addHyperlinkListener(listener);
+ myInheritanceLabel.setBorder(JBUI.Borders.empty(4, 0, 4, 4));
+ }
+
+ @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;
+
+ List<Pair<Boolean, Color>> rainbowState = descriptor.getRainbowColorsInSchemaState();
+ if (rainbowState.size() < myCbStops.length) return;
+ Boolean rainbowOn = descriptor.getColorAndFontGlobalState().isRainbowOn(descriptor.getLanguage());
+ boolean isInherited = false;
+ if (rainbowOn == null) {
+ isInherited = true;
+ rainbowOn = descriptor.getColorAndFontGlobalState().isRainbowOn(null);
+ }
+ myRainbow.setEnabled(!isInherited);
+ myRainbow.setSelected(rainbowOn);
+
+ // the colors are editable only for default language
+ boolean isDefaultLanguage = descriptor.getLanguage() == null;
+ boolean isEnable = !ColorAndFontOptions.isReadOnly(attributeDescriptor.getScheme()) && isDefaultLanguage;
+ //myGradientLabel.setEnabled(isEnable);
+ for (int i = 0; i < myCbStops.length; ++i) {
+ Pair<Boolean, Color> state = rainbowState.get(i);
+ myCbStops[i].setEnabled(isEnable);
+
+ boolean isOverride = state.first;
+ myCbStops[i].setSelected(isOverride);
+
+ myStops[i].setEditable(isEnable && isOverride);
+ myStops[i].setSelectedColor(state.second);
+ }
+
+ myInheritanceLabel.setVisible(!isDefaultLanguage);
+ 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;
+
+ List<Pair<Boolean, Color>> rainbowCurState = descriptor.getRainbowColorsInSchemaState();
+ if (rainbowCurState.size() < myCbStops.length) return;
+
+ boolean isDefaultLanguage = descriptor.getLanguage() == null;
+ descriptor
+ .getColorAndFontGlobalState()
+ .setRainbowOn(descriptor.getLanguage(),
+ isDefaultLanguage ? Boolean.valueOf(myRainbow.isSelected())
+ : myInheritAttributesBox.isSelected() ? null
+ : Boolean.valueOf(myRainbow.isSelected()));
+ for (int i = 0; i < myCbStops.length; ++i) {
+ boolean isOverride = myCbStops[i].isSelected();
+ rainbowCurState.set(i, Pair.create(isOverride,
+ isOverride ? myStops[i].getSelectedColor() : descriptor.getDefaultColor(i)));
+ }
+
+ descriptor.apply(scheme);
+ }
+
+ @Override
+ public void addListener(@NotNull Listener listener) {
+ myDispatcher.addListener(listener);
+ }
+}
}
}
- 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;
}
mySchemeComboBox.setSelectedItem(selectedSchemeBackup);
setListLoaded(true);
- changeToScheme();
-
myDispatcher.getMulticaster().schemeChanged(this);
}
}
import com.intellij.application.options.colors.highlighting.HighlightData;
import com.intellij.application.options.colors.highlighting.HighlightsExtractor;
+import com.intellij.codeHighlighting.RainbowHighlighter;
import com.intellij.ide.highlighter.HighlighterFactory;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.ScrollType;
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.util.EventDispatcher;
import com.intellij.util.ui.UIUtil;
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 void setNavigationBlocked(boolean isNavigationBlocked) {
+ myIsNavigationBlocked = isNavigationBlocked;
+ }
+ private boolean myIsNavigationBlocked = false;
public SimpleEditorPreview(final ColorAndFontOptions options, final ColorSettingsPage page) {
this(options, page, true);
}
+ @NotNull
+ public List<HighlightData> getHighlightDataForExtension() {
+ return myHighlightData;
+ }
+
public SimpleEditorPreview(final ColorAndFontOptions options, final ColorSettingsPage page, final boolean navigatable) {
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) {
+ LogicalPosition pos = myEditor.xyToLogicalPosition(new Point(e.getX(), e.getY()));
+ navigate(myEditor, false, pos, page.getHighlighter(), false);
+ }
+ });
- CaretListener listener = new CaretAdapter() {
+ myEditor.getCaretModel().addCaretListener(new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
- navigate(myEditor, true, e.getNewPosition(), page.getHighlighter(), myHighlightData, false);
+ if (!myIsNavigationBlocked) {
+ navigate(myEditor, true, e.getNewPosition(), page.getHighlighter(), false);
+ }
}
- };
- myEditor.getCaretModel().addCaretListener(listener);
+ });
}
}
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) {
+ final boolean isBackgroundImportant) {
int offset = editor.logicalPositionToOffset(pos);
if (!isBackgroundImportant && editor.offsetToLogicalPosition(offset).column != pos.column) {
}
}
- 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;
+ for (HighlightData highlightData : myHighlightData) {
+ if (ClickNavigator.highlightDataContainsOffset(highlightData, editor.logicalPositionToOffset(pos))) {
+ if (!select) {
+ ClickNavigator.setCursor(editor, Cursor.HAND_CURSOR);
+ }
+ else {
+ myDispatcher.getMulticaster().selectionInPreviewChanged(
+ RainbowHighlighter.isRainbowTempKey(highlightData.getHighlightKey())
+ ? RainbowHighlighter.RAINBOW_TYPE
+ : highlightData.getHighlightType());
}
+ return;
}
}
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);
}
});
@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,
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;
}
}
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;
}
EditorFactory editorFactory = EditorFactory.getInstance();
editorFactory.releaseEditor(myEditor);
stopBlinking();
-
}
}
public String getHighlightType() {
return myHighlightType.getExternalName();
}
+
+ public TextAttributesKey getHighlightKey() {
+ return myHighlightType;
+ }
}
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;
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);
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);
*/
package com.intellij.openapi.options.colors.pages;
+import com.intellij.lang.Language;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.HighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
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;
*
* @author Rustam Vishnyakov
*/
-public class DefaultLanguageColorsPage implements ColorSettingsPage, DisplayPrioritySortable {
+public class DefaultLanguageColorsPage implements RainbowColorSettingsPage, DisplayPrioritySortable {
@NonNls private static final Map<String, TextAttributesKey> TAG_HIGHLIGHTING_MAP = new HashMap<>();
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);
+ }
+
+ @NotNull
+ @Override
+ public String getRainbowDemoText() {
+ return
+ "Global <global_var>variable1</global_var>\n" +
+ "Global <global_var>variable2</global_var>\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>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_tag>@param</doc_tag> <doc_tag_value>parameter5</doc_tag_value> documentation\n" +
+ " */</doc_comment>\n" +
+ "Function <func_decl>declaration</func_decl> (<param>parameter1</param>\n" +
+ " <param>parameter2</param>\n" +
+ " <param>parameter3</param>\n" +
+ " <param>parameter4</param>\n" +
+ " <param>parameter5</param>)\n" +
+ " Local <local_var>variable1</local_var>\n" +
+ " Local <local_var>variable2</local_var>\n" +
+ " Local <local_var>variable3</local_var>\n" +
+ " Local <local_var>variable4</local_var>\n" +
+ " Local <local_var>variable5</local_var>\n" +
+ "Function <func_call>call</func_call>()";
+ }
+
+ @Nullable
+ @Override
+ public Language getLanguage() {
+ return null;
+ }
}
remote.desktop.detected.title=Remote desktop detected
remote.desktop.detected.message=Animation disabled
-checkbox.line.comment.add.space=Add a space at comment start
\ No newline at end of file
+checkbox.line.comment.add.space=Add a space at comment start
+
+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}\u2192Override 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}\u2192Unique color''<br>of <a href="{1}">{2}</html>
+label.rainbow.inheritance.tooltip=<html>''{0}\u2192Unique color'' from<br>''{1}'' section</html>
\ No newline at end of file