Filter out duplicates from icon tooltips (IDEA-248069)
authorDmitry Jemerov <yole@jetbrains.com>
Thu, 13 Aug 2020 15:25:34 +0000 (17:25 +0200)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Thu, 13 Aug 2020 15:26:43 +0000 (15:26 +0000)
GitOrigin-RevId: 524dbf22e750081d4408a050851b5e82b2b7f247

platform/core-ui/src/ui/LayeredIcon.java

index 2fd5fb090f07e7fbc4a7d0c9128d0dacd3cb33b9..370daf3bab99ba3cd4bed9321af29f20a159c4ab 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.ui;
 
 import com.intellij.openapi.diagnostic.Logger;
@@ -15,6 +15,8 @@ import org.jetbrains.annotations.Nullable;
 import javax.swing.*;
 import java.awt.*;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 import static com.intellij.ui.scale.ScaleType.OBJ_SCALE;
 import static com.intellij.ui.scale.ScaleType.USR_SCALE;
@@ -323,7 +325,10 @@ public class LayeredIcon extends JBCachingScalableIcon<LayeredIcon> implements D
     for (Icon icon : icons) {
       if (icon != null) {
         if (singleIcon != null) {
-          return buildCompositeTooltip(icons);
+          StringBuilder result = new StringBuilder();
+          Set<String> seenTooltips = new HashSet<>();
+          buildCompositeTooltip(icons, result, seenTooltips);
+          return result.toString();
         }
         singleIcon = icon;
       }
@@ -334,24 +339,22 @@ public class LayeredIcon extends JBCachingScalableIcon<LayeredIcon> implements D
     return null;
   }
 
-  @Nullable
-  private static String buildCompositeTooltip(Icon[] icons) {
-    StringBuilder result = null;
+  private static void buildCompositeTooltip(Icon[] icons, StringBuilder result, Set<String> seenTooltips) {
     for (int i = 0; i < icons.length; i++) {
       // first layer is the actual object (noun), other layers are modifiers (adjectives), so put first object in last position
       Icon icon = i == icons.length - 1 ? icons[0] : icons[i + 1];
-      if (icon instanceof IconWithToolTip) {
+      if (icon instanceof LayeredIcon) {
+        buildCompositeTooltip(((LayeredIcon) icon).myIcons, result, seenTooltips);
+      }
+      else if (icon instanceof IconWithToolTip) {
         String toolTip = ((IconWithToolTip)icon).getToolTip(true);
-        if (toolTip != null) {
-          if (result == null) {
-            result = new StringBuilder(toolTip);
-          }
-          else {
-            result.append(" ").append(toolTip);
+        if (toolTip != null && seenTooltips.add(toolTip)) {
+          if (result.length() > 0) {
+            result.append(" ");
           }
+          result.append(toolTip);
         }
       }
     }
-    return result != null ? result.toString() : null;
   }
 }