file level inspection ui
authorDmitry Avdeev <Dmitry.Avdeev@jetbrains.com>
Mon, 15 Feb 2010 07:44:19 +0000 (15 10:44 +0300)
committerDmitry Avdeev <Dmitry.Avdeev@jetbrains.com>
Mon, 15 Feb 2010 07:44:19 +0000 (15 10:44 +0300)
platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java
platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionActionWithTextCaching.java
platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionHintComponent.java
platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorInfoPane.java

index 8a09957..93a5870 100644 (file)
@@ -22,10 +22,12 @@ import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
 import com.intellij.lang.annotation.HighlightSeverity;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiFile;
+import com.intellij.ui.EditorNotificationPanel;
 import com.intellij.ui.LightColors;
 
 import javax.swing.*;
@@ -37,44 +39,50 @@ import java.util.List;
 /**
  * @author max
  */
-public class FileLevelIntentionComponent extends JPanel {
+public class FileLevelIntentionComponent extends EditorNotificationPanel {
   private static final Icon ourIntentionIcon = IconLoader.getIcon("/actions/intentionBulb.png");
   private static final Icon ourQuickFixIcon = IconLoader.getIcon("/actions/quickfixBulb.png");
 
   private final Project myProject;
-  private final Editor myEditor;
 
   public FileLevelIntentionComponent(final String description,
                                      final HighlightSeverity severity,
-                                     List<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>> intentions,
+                                     final List<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>> intentions,
                                      final Project project, final PsiFile psiFile, final Editor editor) {
-    super(new BorderLayout());
-    myEditor = editor;
+    super();
     myProject = project;
 
     final ShowIntentionsPass.IntentionsInfo info = new ShowIntentionsPass.IntentionsInfo();
 
     if (intentions != null) {
       for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> intention : intentions) {
-        info.intentionsToShow.add(intention.getFirst());
+        final HighlightInfo.IntentionActionDescriptor descriptor = intention.getFirst();
+        info.intentionsToShow.add(descriptor);
+        createActionLabel(descriptor.getAction().getText(), new Runnable() {
+          public void run() {
+            descriptor.getAction().invoke(project, editor, psiFile);
+          }
+        });
       }
     }
 
-    JLabel content =
-      new JLabel(description, SeverityRegistrar.getInstance(project).compare(severity, HighlightSeverity.ERROR) >= 0 ? ourQuickFixIcon : ourIntentionIcon,
-                 SwingConstants.LEADING);
-    add(content, BorderLayout.WEST);
-    content.setBackground(null);
+    myLabel.setText(description);
+    myLabel.setIcon(SeverityRegistrar.getInstance(project).compare(severity, HighlightSeverity.ERROR) >= 0 ? ourQuickFixIcon : ourIntentionIcon);
     setBackground(getColor(severity));
 
-    content.addMouseListener(new MouseAdapter() {
+    myLabel.addMouseListener(new MouseAdapter() {
       public void mouseClicked(MouseEvent e) {
-        Point location = SwingUtilities.convertPoint(FileLevelIntentionComponent.this,
-                                                     new Point(0, 0),
-                                                     myEditor.getComponent().getRootPane().getLayeredPane());
-        IntentionHintComponent.showIntentionHint(myProject, psiFile, myEditor, info, true, location);
+        IntentionListStep step = new IntentionListStep(null, info, editor, psiFile, project);
+        if (intentions != null && !intentions.isEmpty()) {
+          HighlightInfo.IntentionActionDescriptor descriptor = intentions.get(0).getFirst();
+          IntentionActionWithTextCaching actionWithTextCaching = step.wrapAction(psiFile, descriptor);
+          step = step.getSubStep(actionWithTextCaching, null);
+        }
+        JBPopupFactory.getInstance().createListPopup(step).showUnderneathOf(myLabel);
       }
     });
+
+
   }
 
   private  Color getColor(HighlightSeverity severity) {
index cb923e0..098e3a6 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.intellij.codeInsight.intention.impl;
 
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.diagnostic.Logger;
@@ -37,11 +38,15 @@ class IntentionActionWithTextCaching implements Comparable<IntentionActionWithTe
   private final List<IntentionAction> myOptionInspectionFixes;
   private final Icon myIcon;
 
-  IntentionActionWithTextCaching(IntentionAction action, String displayName){
-    this(action, displayName, null);
+  IntentionActionWithTextCaching(IntentionAction action){
+    this(action, action.getText(), null);
   }
 
-  IntentionActionWithTextCaching(IntentionAction action, String displayName, Icon icon) {
+  IntentionActionWithTextCaching(HighlightInfo.IntentionActionDescriptor action){
+    this(action.getAction(), action.getDisplayName(), action.getIcon());
+  }
+
+  private IntentionActionWithTextCaching(IntentionAction action, String displayName, Icon icon) {
     myIcon = icon;
     myOptionIntentions = new ArrayList<IntentionAction>();
     myOptionErrorFixes = new ArrayList<IntentionAction>();
index 851694d..bf9f82d 100644 (file)
@@ -102,7 +102,7 @@ public class IntentionHintComponent extends JPanel implements Disposable, Scroll
   }
 
   public static IntentionHintComponent showIntentionHint(Project project, final PsiFile file, Editor editor,
-                                                         ShowIntentionsPass.IntentionsInfo intentions,
+                                                         @NotNull ShowIntentionsPass.IntentionsInfo intentions,
                                                          boolean showExpanded,
                                                          final Point position) {
     final IntentionHintComponent component = new IntentionHintComponent(project, file, editor, intentions);
@@ -199,7 +199,8 @@ public class IntentionHintComponent extends JPanel implements Disposable, Scroll
     return new Point(location.x, location.y);
   }
 
-  private IntentionHintComponent(@NotNull Project project, @NotNull PsiFile file, @NotNull Editor editor, ShowIntentionsPass.IntentionsInfo intentions) {
+  private IntentionHintComponent(@NotNull Project project, @NotNull PsiFile file, @NotNull Editor editor,
+                                 @NotNull ShowIntentionsPass.IntentionsInfo intentions) {
     ApplicationManager.getApplication().assertReadAccessAllowed();
     myFile = file;
     myEditor = editor;
index 7a2d8d9..b4be70a 100644 (file)
@@ -36,6 +36,7 @@ import com.intellij.psi.util.PsiUtilBase;
 import gnu.trove.THashSet;
 import gnu.trove.TObjectHashingStrategy;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.util.*;
@@ -49,6 +50,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
   private final Set<IntentionActionWithTextCaching> myCachedInspectionFixes = new THashSet<IntentionActionWithTextCaching>(ACTION_TEXT_AND_CLASS_EQUALS);
   private final Set<IntentionActionWithTextCaching> myCachedGutters = new THashSet<IntentionActionWithTextCaching>(ACTION_TEXT_AND_CLASS_EQUALS);
   private final IntentionManagerSettings mySettings;
+  @Nullable
   private final IntentionHintComponent myIntentionHintComponent;
   private final Editor myEditor;
   private final PsiFile myFile;
@@ -64,7 +66,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
   };
   private Runnable myFinalRunnable;
 
-  IntentionListStep(IntentionHintComponent intentionHintComponent, ShowIntentionsPass.IntentionsInfo intentions, Editor editor, PsiFile file,
+  IntentionListStep(@Nullable IntentionHintComponent intentionHintComponent, ShowIntentionsPass.IntentionsInfo intentions, Editor editor, PsiFile file,
                     Project project) {
     myIntentionHintComponent = intentionHintComponent;
     myEditor = editor;
@@ -102,29 +104,34 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
     for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
       IntentionAction action = descriptor.getAction();
       if (!isAvailable(action, element)) continue;
-      IntentionActionWithTextCaching cachedAction = new IntentionActionWithTextCaching(action, descriptor.getDisplayName(), descriptor.getIcon());
-      result &= !cachedActions.add(cachedAction);
       if (element == null) continue;
-      final List<IntentionAction> options = descriptor.getOptions(element);
-      if (options != null) {
-        for (IntentionAction option : options) {
-          if (!option.isAvailable(myProject, myEditor, element.getContainingFile())) continue;
-          IntentionActionWithTextCaching textCaching = new IntentionActionWithTextCaching(option, option.getText());
-          boolean isErrorFix = myCachedErrorFixes.contains(textCaching);
-          if (isErrorFix) {
-            cachedAction.addErrorFix(option);
-          }
-          boolean isInspectionFix = myCachedInspectionFixes.contains(textCaching);
-          if (isInspectionFix) {
-            cachedAction.addInspectionFix(option);
-          }
-          else {
-            cachedAction.addIntention(option);
-          }
+      IntentionActionWithTextCaching cachedAction = wrapAction(element, descriptor);
+      result &= !cachedActions.add(cachedAction);
+    }
+    return result;
+  }
+
+  IntentionActionWithTextCaching wrapAction(PsiElement element, HighlightInfo.IntentionActionDescriptor descriptor) {
+    IntentionActionWithTextCaching cachedAction = new IntentionActionWithTextCaching(descriptor);
+    final List<IntentionAction> options = descriptor.getOptions(element);
+    if (options != null) {
+      for (IntentionAction option : options) {
+        if (!option.isAvailable(myProject, myEditor, element.getContainingFile())) continue;
+        IntentionActionWithTextCaching textCaching = new IntentionActionWithTextCaching(option);
+        boolean isErrorFix = myCachedErrorFixes.contains(textCaching);
+        if (isErrorFix) {
+          cachedAction.addErrorFix(option);
+        }
+        boolean isInspectionFix = myCachedInspectionFixes.contains(textCaching);
+        if (isInspectionFix) {
+          cachedAction.addInspectionFix(option);
+        }
+        else {
+          cachedAction.addIntention(option);
         }
       }
     }
-    return result;
+    return cachedAction;
   }
 
   private boolean removeInvalidActions(final Collection<IntentionActionWithTextCaching> cachedActions, final PsiElement element) {
@@ -160,7 +167,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
     }
 
     if (hasSubstep(action)) {
-      return getSubStep(action);
+      return getSubStep(action, action.getToolName());
     }
 
     return FINAL_CHOICE;
@@ -190,7 +197,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
     };
   }
 
-  private PopupStep getSubStep(final IntentionActionWithTextCaching action) {
+  IntentionListStep getSubStep(final IntentionActionWithTextCaching action, final String title) {
     ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
     for (final IntentionAction optionIntention : action.getOptionIntentions()) {
       intentions.intentionsToShow.add(new HighlightInfo.IntentionActionDescriptor(optionIntention, null));
@@ -204,7 +211,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
 
     return new IntentionListStep(myIntentionHintComponent, intentions,myEditor, myFile, myProject){
       public String getTitle() {
-        return action.getToolName();
+        return title;
       }
     };
   }
@@ -284,7 +291,9 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
   }
 
   public void canceled() {
-    myIntentionHintComponent.canceled(this);
+    if (myIntentionHintComponent != null) {
+      myIntentionHintComponent.canceled(this);
+    }
   }
 
   public int getDefaultOptionIndex() { return 0; }
index f531af0..759ad4f 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.intellij.openapi.fileEditor.impl;
 
-import com.intellij.ui.IdeBorderFactory;
-
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
@@ -61,7 +59,6 @@ public class FileEditorInfoPane extends JPanel {
         updateButtons();
       }
     });
-    setBorder(IdeBorderFactory.createBorder());
 
     add(myButtonsPanel, BorderLayout.EAST);
     myButtonsPanel.setVisible(false);