console filters: better grayed hyperlink support (http://crucible.labs.intellij.net...
authorSergey Simonchik <sergey.simonchik@jetbrains.com>
Wed, 4 Mar 2015 12:33:21 +0000 (15:33 +0300)
committerSergey Simonchik <sergey.simonchik@jetbrains.com>
Wed, 4 Mar 2015 12:33:21 +0000 (15:33 +0300)
platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java
platform/lang-api/src/com/intellij/execution/filters/Filter.java
platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java

index 5bdf700b4387eefc3dcb37b35c207949afa5d335..7163bd5a397098b494db0d0f0d4030212edba815 100644 (file)
@@ -86,7 +86,7 @@ public class CompositeFilter implements Filter, FilterMixin {
     if (resultItems.size() == 1) {
       ResultItem resultItem = resultItems.get(0);
       return new Result(resultItem.getHighlightStartOffset(), resultItem.getHighlightEndOffset(), resultItem.getHyperlinkInfo(),
-                        resultItem.getHighlightAttributes());
+                        resultItem.getHighlightAttributes(), resultItem.getFollowedHyperlinkAttributes());
     }
     return new Result(resultItems);
   }
index c1df6860065f816317c05f2f24ed984c348237c5..6a22b2a73db3ba5dab9750ed47ff2920a4a58634 100644 (file)
  */
 package com.intellij.execution.filters;
 
-import com.intellij.openapi.editor.colors.CodeInsightColors;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.colors.*;
 import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author Yura Cangea
@@ -35,15 +37,15 @@ public interface Filter {
 
   class Result extends ResultItem {
 
-    private static final TextAttributes INACTIVE_HYPERLINK_ATTRIBUTES;
+    private static final Map<TextAttributesKey, TextAttributes> GRAYED_BY_NORMAL_CACHE = ContainerUtil.newConcurrentMap(2);
     static {
-      TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES);
-      if (attributes != null) {
-        attributes = attributes.clone();
-        attributes.setForegroundColor(UIUtil.getInactiveTextColor());
-        attributes.setEffectColor(UIUtil.getInactiveTextColor());
-      }
-      INACTIVE_HYPERLINK_ATTRIBUTES = attributes;
+      EditorColorsManager.getInstance().addEditorColorsListener(new EditorColorsListener() {
+        @Override
+        public void globalSchemeChange(EditorColorsScheme scheme) {
+          // invalidate cache on Appearance Theme/Editor Scheme change
+          GRAYED_BY_NORMAL_CACHE.clear();
+        }
+      }, ApplicationManager.getApplication());
     }
 
     protected NextAction myNextAction = NextAction.EXIT;
@@ -57,20 +59,31 @@ public interface Filter {
                   final int highlightEndOffset,
                   @Nullable final HyperlinkInfo hyperlinkInfo,
                   @Nullable final TextAttributes highlightAttributes) {
-      super(highlightStartOffset, highlightEndOffset, hyperlinkInfo, highlightAttributes);
+      super(highlightStartOffset, highlightEndOffset, hyperlinkInfo, highlightAttributes, null);
+      myResultItems = null;
+    }
+
+    public Result(final int highlightStartOffset,
+                  final int highlightEndOffset,
+                  @Nullable final HyperlinkInfo hyperlinkInfo,
+                  @Nullable final TextAttributes highlightAttributes,
+                  @Nullable final TextAttributes followedHyperlinkAttributes) {
+      super(highlightStartOffset, highlightEndOffset, hyperlinkInfo, highlightAttributes, followedHyperlinkAttributes);
       myResultItems = null;
     }
 
     public Result(final int highlightStartOffset,
                   final int highlightEndOffset,
                   @Nullable final HyperlinkInfo hyperlinkInfo,
-                  boolean inactiveHyperlink) {
-      super(highlightStartOffset, highlightEndOffset, hyperlinkInfo, inactiveHyperlink ? INACTIVE_HYPERLINK_ATTRIBUTES : null);
+                  final boolean grayedHyperlink) {
+      super(highlightStartOffset, highlightEndOffset, hyperlinkInfo,
+            grayedHyperlink ? getGrayedHyperlinkAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES) : null,
+            grayedHyperlink ? getGrayedHyperlinkAttributes(CodeInsightColors.FOLLOWED_HYPERLINK_ATTRIBUTES) : null);
       myResultItems = null;
     }
 
     public Result(@NotNull List<ResultItem> resultItems) {
-      super(-1, -1, null, null);
+      super(-1, -1, null, null, null);
       myResultItems = resultItems;
     }
 
@@ -142,6 +155,22 @@ public interface Filter {
     public void setNextAction(NextAction nextAction) {
       myNextAction = nextAction;
     }
+
+    @Nullable
+    private static TextAttributes getGrayedHyperlinkAttributes(@NotNull TextAttributesKey normalHyperlinkAttrsKey) {
+      EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
+      TextAttributes grayedHyperlinkAttrs = GRAYED_BY_NORMAL_CACHE.get(normalHyperlinkAttrsKey);
+      if (grayedHyperlinkAttrs == null) {
+        TextAttributes normalHyperlinkAttrs = globalScheme.getAttributes(normalHyperlinkAttrsKey);
+        if (normalHyperlinkAttrs != null) {
+          grayedHyperlinkAttrs = normalHyperlinkAttrs.clone();
+          grayedHyperlinkAttrs.setForegroundColor(UIUtil.getInactiveTextColor());
+          grayedHyperlinkAttrs.setEffectColor(UIUtil.getInactiveTextColor());
+          GRAYED_BY_NORMAL_CACHE.put(normalHyperlinkAttrsKey, grayedHyperlinkAttrs);
+        }
+      }
+      return grayedHyperlinkAttrs;
+    }
   }
 
   enum NextAction {
@@ -170,9 +199,11 @@ public interface Filter {
     @Deprecated @Nullable
     public final HyperlinkInfo hyperlinkInfo;
 
+    private final TextAttributes myFollowedHyperlinkAttributes;
+
     @SuppressWarnings("deprecation")
     public ResultItem(final int highlightStartOffset, final int highlightEndOffset, @Nullable final HyperlinkInfo hyperlinkInfo) {
-      this(highlightStartOffset, highlightEndOffset, hyperlinkInfo, null);
+      this(highlightStartOffset, highlightEndOffset, hyperlinkInfo, null, null);
     }
 
     @SuppressWarnings("deprecation")
@@ -180,10 +211,20 @@ public interface Filter {
                       final int highlightEndOffset,
                       @Nullable final HyperlinkInfo hyperlinkInfo,
                       @Nullable final TextAttributes highlightAttributes) {
+      this(highlightStartOffset, highlightEndOffset, hyperlinkInfo, highlightAttributes, null);
+    }
+
+    @SuppressWarnings("deprecation")
+    public ResultItem(final int highlightStartOffset,
+                      final int highlightEndOffset,
+                      @Nullable final HyperlinkInfo hyperlinkInfo,
+                      @Nullable final TextAttributes highlightAttributes,
+                      @Nullable final TextAttributes followedHyperlinkAttributes) {
       this.highlightStartOffset = highlightStartOffset;
       this.highlightEndOffset = highlightEndOffset;
       this.hyperlinkInfo = hyperlinkInfo;
       this.highlightAttributes = highlightAttributes;
+      myFollowedHyperlinkAttributes = followedHyperlinkAttributes;
     }
 
     public int getHighlightStartOffset() {
@@ -202,6 +243,11 @@ public interface Filter {
       return highlightAttributes;
     }
 
+    @Nullable
+    public TextAttributes getFollowedHyperlinkAttributes() {
+      return myFollowedHyperlinkAttributes;
+    }
+
     @Nullable
     public HyperlinkInfo getHyperlinkInfo() {
       //noinspection deprecation
index 67d655fd0bad6138f673808d7bae76c2d566bba6..36da53448c7b664c6e883e65beae76020af01f99 100644 (file)
@@ -214,22 +214,37 @@ public class EditorHyperlinkSupport {
   }
 
   @NotNull
-  public RangeHighlighter createHyperlink(final int highlightStartOffset,
-                                          final int highlightEndOffset,
-                                          @Nullable final TextAttributes highlightAttributes,
-                                          @NotNull final HyperlinkInfo hyperlinkInfo) {
+  public RangeHighlighter createHyperlink(int highlightStartOffset,
+                                          int highlightEndOffset,
+                                          @Nullable TextAttributes highlightAttributes,
+                                          @NotNull HyperlinkInfo hyperlinkInfo) {
+    return createHyperlink(highlightStartOffset, highlightEndOffset, highlightAttributes, hyperlinkInfo, null);
+  }
+
+  @NotNull
+  private RangeHighlighter createHyperlink(final int highlightStartOffset,
+                                           final int highlightEndOffset,
+                                           @Nullable final TextAttributes highlightAttributes,
+                                           @NotNull final HyperlinkInfo hyperlinkInfo,
+                                           @Nullable TextAttributes followedHyperlinkAttributes) {
     TextAttributes textAttributes = highlightAttributes != null ? highlightAttributes : getHyperlinkAttributes();
     final RangeHighlighter highlighter = myEditor.getMarkupModel().addRangeHighlighter(highlightStartOffset,
                                                                                        highlightEndOffset,
                                                                                        HYPERLINK_LAYER,
                                                                                        textAttributes,
                                                                                        HighlighterTargetArea.EXACT_RANGE);
-    associateHyperlink(highlighter, hyperlinkInfo);
+    associateHyperlink(highlighter, hyperlinkInfo, followedHyperlinkAttributes);
     return highlighter;
   }
 
   public static void associateHyperlink(@NotNull RangeHighlighter highlighter, @NotNull HyperlinkInfo hyperlinkInfo) {
-    highlighter.putUserData(HYPERLINK, new HyperlinkInfoTextAttributes(hyperlinkInfo));
+    associateHyperlink(highlighter, hyperlinkInfo, null);
+  }
+
+  private static void associateHyperlink(@NotNull RangeHighlighter highlighter,
+                                        @NotNull HyperlinkInfo hyperlinkInfo,
+                                        @Nullable TextAttributes followedHyperlinkAttributes) {
+    highlighter.putUserData(HYPERLINK, new HyperlinkInfoTextAttributes(hyperlinkInfo, followedHyperlinkAttributes));
   }
 
   @Nullable
@@ -277,7 +292,7 @@ public class EditorHyperlinkSupport {
 
           TextAttributes attributes = resultItem.getHighlightAttributes();
           if (resultItem.getHyperlinkInfo() != null) {
-            createHyperlink(start, end, attributes, resultItem.getHyperlinkInfo());
+            createHyperlink(start, end, attributes, resultItem.getHyperlinkInfo(), resultItem.getFollowedHyperlinkAttributes());
           }
           else if (attributes != null) {
             addHighlighter(start, end, attributes);
@@ -296,8 +311,14 @@ public class EditorHyperlinkSupport {
     return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES);
   }
 
-  private static TextAttributes getFollowedHyperlinkAttributes() {
-    return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.FOLLOWED_HYPERLINK_ATTRIBUTES);
+  @NotNull
+  private static TextAttributes getFollowedHyperlinkAttributes(@NotNull RangeHighlighter range) {
+    HyperlinkInfoTextAttributes attrs = HYPERLINK.get(range);
+    TextAttributes result = attrs != null ? attrs.getFollowedHyperlinkAttributes() : null;
+    if (result == null) {
+      result = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.FOLLOWED_HYPERLINK_ATTRIBUTES);
+    }
+    return result;
   }
 
   @Nullable
@@ -346,7 +367,7 @@ public class EditorHyperlinkSupport {
       }
       if (range == link) {
         range.putUserData(OLD_HYPERLINK_TEXT_ATTRIBUTES, range.getTextAttributes());
-        markupModel.setRangeHighlighterAttributes(range, getFollowedHyperlinkAttributes());
+        markupModel.setRangeHighlighterAttributes(range, getFollowedHyperlinkAttributes(range));
       }
     }
     //refresh highlighter text attributes
@@ -363,15 +384,22 @@ public class EditorHyperlinkSupport {
   }
 
   private static class HyperlinkInfoTextAttributes extends TextAttributes {
-    private HyperlinkInfo myHyperlinkInfo;
+    private final HyperlinkInfo myHyperlinkInfo;
+    private final TextAttributes myFollowedHyperlinkAttributes;
 
-    public HyperlinkInfoTextAttributes(@NotNull HyperlinkInfo hyperlinkInfo) {
+    public HyperlinkInfoTextAttributes(@NotNull HyperlinkInfo hyperlinkInfo, @Nullable TextAttributes followedHyperlinkAttributes) {
       myHyperlinkInfo = hyperlinkInfo;
+      myFollowedHyperlinkAttributes = followedHyperlinkAttributes;
     }
 
     @NotNull
     public HyperlinkInfo getHyperlinkInfo() {
       return myHyperlinkInfo;
     }
+
+    @Nullable
+    public TextAttributes getFollowedHyperlinkAttributes() {
+      return myFollowedHyperlinkAttributes;
+    }
   }
 }