correct rendering of traffic light
authorAlexey Kudravtsev <cdr@intellij.com>
Fri, 10 Sep 2010 09:04:35 +0000 (13:04 +0400)
committerAlexey Kudravtsev <cdr@intellij.com>
Fri, 10 Sep 2010 09:10:23 +0000 (13:10 +0400)
more informative tooltip

26 files changed:
platform/lang-impl/src/com/intellij/application/options/colors/FontEditorPreview.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPassFactory.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPassFactory.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficTooltipRendererImpl.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TruncatingIcon.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WolfHighlightingPass.java
platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java
platform/platform-impl/src/com/intellij/codeInsight/hint/LineTooltipRenderer.java
platform/platform-impl/src/com/intellij/openapi/editor/ex/ErrorStripTooltipRendererProvider.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/TrafficTooltipRenderer.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorImpl.java
platform/platform-resources-en/src/messages/DaemonBundle.properties
xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementsErrorPanel.java

index d72713820375ee34e6da33a37eccf9c9b2034dd4..33add956d0d499077196c973929787dca11ab908 100644 (file)
@@ -27,7 +27,6 @@ import com.intellij.util.EventDispatcher;
 import org.jetbrains.annotations.Nls;
 
 import java.awt.*;
-import java.util.ArrayList;
 
 public class FontEditorPreview implements PreviewPanel{
   private final EditorEx myEditor;
@@ -60,7 +59,6 @@ public class FontEditorPreview implements PreviewPanel{
       protected DaemonCodeAnalyzerStatus getDaemonCodeAnalyzerStatus(boolean fillErrorsCount) {
         DaemonCodeAnalyzerStatus status = new DaemonCodeAnalyzerStatus();
         status.errorAnalyzingFinished = true;
-        status.passStati = new ArrayList<DaemonCodeAnalyzerStatus.PassStatus>();
         status.errorCount = new int[]{1, 2};
         return status;
       }
index ca0ecc6f156e9e8d2c40318043f252631e328bdd..15d2d5e8375416a1ce436795001aab57dbda2248 100644 (file)
@@ -28,7 +28,6 @@ import com.intellij.codeInsight.hint.HintManager;
 import com.intellij.codeInsight.intention.impl.IntentionHintComponent;
 import com.intellij.concurrency.Job;
 import com.intellij.ide.PowerSaveMode;
-import com.intellij.injected.editor.EditorWindow;
 import com.intellij.lang.annotation.HighlightSeverity;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
@@ -43,7 +42,6 @@ import com.intellij.openapi.editor.markup.RangeHighlighter;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
 import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.fileTypes.StdFileTypes;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -89,8 +87,6 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
   private final EditorTracker myEditorTracker;
   private DaemonProgressIndicator myUpdateProgress = new DaemonProgressIndicator(); //guarded by this
 
-  private DaemonProgressIndicator myUpdateVisibleProgress = new DaemonProgressIndicator(); //guarded by this
-
   private final Runnable myUpdateRunnable = createUpdateRunnable();
 
   private final Alarm myAlarm = new Alarm();
@@ -311,37 +307,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
 
   public void updateVisibleHighlighters(@NotNull Editor editor) {
     ApplicationManager.getApplication().assertIsDispatchThread();
-    if (true) return;  // no need, will not work anyway
-
-    if (!myUpdateByTimerEnabled) return;
-    if (editor instanceof EditorWindow) editor = ((EditorWindow)editor).getDelegate();
-
-    final TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
-    BackgroundEditorHighlighter highlighter = textEditor.getBackgroundHighlighter();
-    if (highlighter == null) return;
-    final HighlightingPass[] highlightingPasses = highlighter.createPassesForVisibleArea();
-
-    DaemonProgressIndicator progress;
-    synchronized (this) {
-      recreateVisibleProgress();
-
-      progress = myUpdateVisibleProgress;
-    }
-    myPassExecutorService.renewVisiblePasses(textEditor, highlightingPasses, progress);
-  }
-
-  private synchronized void cancelVisibleProgress() {
-    if (myUpdateVisibleProgress != null) {
-      myUpdateVisibleProgress.cancel();
-      myUpdateVisibleProgress = null;
-    }
-  }
-
-  private synchronized void recreateVisibleProgress() {
-    if (myUpdateVisibleProgress == null) {
-      myUpdateVisibleProgress = new DaemonProgressIndicator();
-      myUpdateVisibleProgress.start();
-    }
+    // no need, will not work anyway
   }
 
   public void setUpdateByTimerEnabled(boolean value) {
@@ -404,8 +370,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
     stopProcess(true);
   }
 
-  public List<TextEditorHighlightingPass> getPassesToShowProgressFor(PsiFile file) {
-    Document document = PsiDocumentManager.getInstance(myProject).getDocument(file);
+  public List<TextEditorHighlightingPass> getPassesToShowProgressFor(Document document) {
     List<TextEditorHighlightingPass> allPasses = myPassExecutorService.getAllSubmittedPasses();
     List<TextEditorHighlightingPass> result = new ArrayList<TextEditorHighlightingPass>(allPasses.size());
     for (TextEditorHighlightingPass pass : allPasses) {
@@ -416,7 +381,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
     return result;
   }
 
-  public boolean isAllAnalysisFinished(PsiFile file) {
+  public boolean isAllAnalysisFinished(@NotNull PsiFile file) {
     if (myDisposed) return false;
     Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file);
     return document != null &&
@@ -462,17 +427,10 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
     if (myUpdateProgress != null) {
       myUpdateProgress.cancel();
       myPassExecutorService.cancelAll(false);
-      cancelVisibleProgress();
       myUpdateProgress = null;
     }
   }
 
-  private static DaemonProgressIndicator recreateProgress() {
-    DaemonProgressIndicator myUpdateProgress = new DaemonProgressIndicator();
-    myUpdateProgress.start();
-    return myUpdateProgress;
-  }
-
   public static boolean processHighlights(@NotNull Document document,
                                           @NotNull Project project,
                                           @Nullable("null means all") final HighlightSeverity minSeverity,
@@ -748,7 +706,9 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
         myAlarm.cancelAllRequests();
         DaemonProgressIndicator progress;
         synchronized (DaemonCodeAnalyzerImpl.this) {
-          myUpdateProgress = progress = recreateProgress();
+          DaemonProgressIndicator indicator = new DaemonProgressIndicator();
+          indicator.start();
+          myUpdateProgress = progress = indicator;
         }
         myPassExecutorService.submitPasses(passes, progress, Job.DEFAULT_PRIORITY);
       }
index 34c25858f2abf430cbe83d0bcef022f95f13324c..2757f55df94c2e8dd58cee2b9dae96cb0eb382cc 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.codeInsight.hint.TooltipRenderer;
 import com.intellij.openapi.actionSystem.IdeActions;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.ex.ErrorStripTooltipRendererProvider;
+import com.intellij.openapi.editor.impl.TrafficTooltipRenderer;
 import com.intellij.openapi.editor.markup.RangeHighlighter;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.keymap.KeymapManager;
@@ -107,6 +108,11 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP
     return new MyRenderer(text, width);
   }
 
+  @Override
+  public TrafficTooltipRenderer createTrafficTooltipRenderer(Runnable onHide) {
+    return new TrafficTooltipRendererImpl(onHide);
+  }
+
   private static class MyRenderer extends LineTooltipRenderer {
     public MyRenderer(final String text) {
       super(text);
index a24a44a49926139c235b08901bd0c8d239b38819..b340d77e8f4cb3b9af59580600d6057104db122b 100644 (file)
@@ -61,7 +61,6 @@ import com.intellij.util.ui.UIUtil;
 import gnu.trove.THashSet;
 import org.jetbrains.annotations.NotNull;
 
-import javax.swing.*;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
@@ -69,7 +68,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingPass implements DumbAware {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass");
-  static final Icon IN_PROGRESS_ICON = IconLoader.getIcon("/general/errorsInProgress.png");
   static final String PRESENTABLE_NAME = DaemonBundle.message("pass.syntax");
   private static final Key<Boolean> HAS_ERROR_ELEMENT = Key.create("HAS_ERROR_ELEMENT");
 
@@ -105,7 +103,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
                                  int endOffset,
                                  boolean updateAll,
                                  @NotNull TextRange priorityRange) {
-    super(project, document, IN_PROGRESS_ICON, PRESENTABLE_NAME, file, true);
+    super(project, document, PRESENTABLE_NAME, file, true);
     myStartOffset = startOffset;
     myEndOffset = endOffset;
     myUpdateAll = updateAll;
index 57e6d6de47db6804a5165847bcc5630a00559f69..4e9b7c5c796790227a721c25c8aee8ae1bc42b93 100644 (file)
@@ -49,8 +49,8 @@ public class GeneralHighlightingPassFactory extends AbstractProjectComponent imp
   @Nullable
   public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
     TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.UPDATE_ALL);
-    if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument(), GeneralHighlightingPass.IN_PROGRESS_ICON,
-                                                                             GeneralHighlightingPass.PRESENTABLE_NAME);
+    if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument()
+    );
     TextRange visibleRange = VisibleHighlightingPassFactory.calculateVisibleRange(editor);
     return new GeneralHighlightingPass(myProject, file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), true, visibleRange);
   }
index 4e89937ced6870b8a49b2ae572f4e1b42bf47998..dcf913602e92011ee50468ac167203dbe5a31522 100644 (file)
@@ -64,7 +64,7 @@ public class LineMarkersPass extends ProgressableTextEditorHighlightingPass impl
                          int startOffset,
                          int endOffset,
                          boolean updateAll) {
-    super(project, document, GeneralHighlightingPass.IN_PROGRESS_ICON, GeneralHighlightingPass.PRESENTABLE_NAME, file,
+    super(project, document, GeneralHighlightingPass.PRESENTABLE_NAME, file,
           false);
     myStartOffset = startOffset;
     myEndOffset = endOffset;
index 7472f823fdc4552af160191b092fab70dbffb6e4..67b32481b0f6d1977abb3b530ef711e0eec8c30c 100644 (file)
@@ -47,8 +47,8 @@ public class LineMarkersPassFactory extends AbstractProjectComponent implements
   @Nullable
   public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
     TextRange textRange = calculateRangeToProcessForSyntaxPass(editor);
-    if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument(), GeneralHighlightingPass.IN_PROGRESS_ICON,
-                                                                             GeneralHighlightingPass.PRESENTABLE_NAME);
+    if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument()
+    );
     return new LineMarkersPass(myProject, file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), true);
   }
 
index 74973d29af8050b870e1e4d7fe3c7df457579a0a..3fd719ec070bd5bb838641f00a7190dea8fb0bbd 100644 (file)
@@ -45,7 +45,6 @@ import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.progress.util.ProgressWrapper;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.DumbService;
-import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.Trinity;
@@ -64,7 +63,6 @@ import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import javax.swing.*;
 import java.util.*;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ConcurrentMap;
@@ -81,7 +79,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
   private final ConcurrentMap<PsiFile, List<InspectionResult>> result = new ConcurrentHashMap<PsiFile, List<InspectionResult>>();
   static final String PRESENTABLE_NAME = DaemonBundle.message("pass.inspection");
   private volatile List<HighlightInfo> myInfos = Collections.emptyList();
-  static final Icon IN_PROGRESS_ICON = IconLoader.getIcon("/general/inspectionInProgress.png");
   private final String myShortcutText;
   private final SeverityRegistrar mySeverityRegistrar;
   private final InspectionProfileWrapper myProfileWrapper;
@@ -91,7 +88,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
     this(file, document, startOffset, endOffset, new TextRange(0, 0));
   }
   public LocalInspectionsPass(@NotNull PsiFile file, @Nullable Document document, int startOffset, int endOffset, @NotNull TextRange priorityRange) {
-    super(file.getProject(), document, IN_PROGRESS_ICON, PRESENTABLE_NAME, file, true);
+    super(file.getProject(), document, PRESENTABLE_NAME, file, true);
     myStartOffset = startOffset;
     myEndOffset = endOffset;
     myPriorityRange = priorityRange;
index 44a3304bfe5de5670ff27016e51e2c5fbd8ec356..327772a905a3933e3e1d1f2d403221b57c7154b8 100644 (file)
@@ -52,8 +52,8 @@ public class LocalInspectionsPassFactory extends AbstractProjectComponent implem
   @Nullable
   public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
     TextRange textRange = calculateRangeToProcess(editor);
-    if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument(), LocalInspectionsPass.IN_PROGRESS_ICON,
-                                                                             LocalInspectionsPass.PRESENTABLE_NAME);
+    if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument()
+    );
     TextRange visibleRange = VisibleHighlightingPassFactory.calculateVisibleRange(editor);
     return new LocalInspectionsPass(file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), visibleRange){
       List<LocalInspectionTool> getInspectionTools(InspectionProfileWrapper profile) {
index 7a357134fba35eec0c689620d2bd20d1147b93d1..93509511ad42abe0b93bdf493156b87d53bf7427 100644 (file)
@@ -163,7 +163,7 @@ public abstract class PassExecutorService implements Disposable {
       List<TextEditorHighlightingPass> passes = textPasses.get(fileEditors.get(0));
       threadsToStartCountdown.addAndGet(passes.size());
 
-      // create one scheduled pass per unique id (possibly for multiple fileeditors. they all will be applied at the pass finish)
+      // create one scheduled pass per unique id (possibly for multiple file editors. they all will be applied at the pass finish)
       ContainerUtil.quickSort(passes, new Comparator<TextEditorHighlightingPass>() {
         public int compare(final TextEditorHighlightingPass o1, final TextEditorHighlightingPass o2) {
           return o1.getId() - o2.getId();
@@ -209,7 +209,7 @@ public abstract class PassExecutorService implements Disposable {
     toBeSubmitted.put(key, scheduledPass);
     for (int predecessorId : pass.getCompletionPredecessorIds()) {
       ScheduledPass predecessor = findOrCreatePredecessorPass(fileEditors, document, toBeSubmitted, textEditorHighlightingPasses, freePasses,
-                                                              updateProgress, threadsToStartCountdown, jobPriority, predecessorId, passId);
+                                                              updateProgress, threadsToStartCountdown, jobPriority, predecessorId);
       if (predecessor != null) {
         predecessor.mySuccessorsOnCompletion.add(scheduledPass);
         scheduledPass.myRunningPredecessorsCount.incrementAndGet();
@@ -217,7 +217,7 @@ public abstract class PassExecutorService implements Disposable {
     }
     for (int predecessorId : pass.getStartingPredecessorIds()) {
       ScheduledPass predecessor = findOrCreatePredecessorPass(fileEditors, document, toBeSubmitted, textEditorHighlightingPasses, freePasses,
-                                                              updateProgress, threadsToStartCountdown, jobPriority, predecessorId, passId);
+                                                              updateProgress, threadsToStartCountdown, jobPriority, predecessorId);
       if (predecessor != null) {
         predecessor.mySuccessorsOnSubmit.add(scheduledPass);
         scheduledPass.myRunningPredecessorsCount.incrementAndGet();
@@ -237,9 +237,9 @@ public abstract class PassExecutorService implements Disposable {
                                                     final DaemonProgressIndicator updateProgress,
                                                     final AtomicInteger myThreadsToStartCountdown,
                                                     final int jobPriority,
-                                                    final int predecessorId, int passId) {
-    Pair<Document, Integer> predkey = Pair.create(document, predecessorId);
-    ScheduledPass predecessor = toBeSubmitted.get(predkey);
+                                                    final int predecessorId) {
+    Pair<Document, Integer> predKey = Pair.create(document, predecessorId);
+    ScheduledPass predecessor = toBeSubmitted.get(predKey);
     if (predecessor == null) {
       TextEditorHighlightingPass textEditorPass = findPassById(predecessorId, textEditorHighlightingPasses);
       predecessor = textEditorPass == null ? null : createScheduledPass(fileEditors, textEditorPass, toBeSubmitted, textEditorHighlightingPasses, freePasses,
@@ -264,7 +264,6 @@ public abstract class PassExecutorService implements Disposable {
       Job<Void> job = JobUtil.submitToJobThread(pass, pass.myJobPriority, new Consumer<Future>() {
         @Override
         public void consume(Future future) {
-          mySubmittedPasses.remove(pass);
           try {
             future.get();
           }
@@ -281,18 +280,6 @@ public abstract class PassExecutorService implements Disposable {
     }
   }
 
-  public void renewVisiblePasses(final TextEditor textEditor, final HighlightingPass[] highlightingPasses,
-                          final DaemonProgressIndicator visibleProgress) {
-    for (ScheduledPass pass : mySubmittedPasses.keySet()) {
-      if (pass.myUpdateProgress == visibleProgress) {
-        return; //already scheduled. whenever something changes, it will be rescheduled anyway
-      }
-    }
-    Map<FileEditor, HighlightingPass[]> passes = Collections.<FileEditor, HighlightingPass[]>singletonMap(textEditor, highlightingPasses);
-    // higher priority
-    submitPasses(passes, visibleProgress, Job.DEFAULT_PRIORITY-10);
-  }
-
   private class ScheduledPass implements Runnable {
     private final List<FileEditor> myFileEditors;
     private final TextEditorHighlightingPass myPass;
@@ -451,12 +438,18 @@ public abstract class PassExecutorService implements Disposable {
   protected abstract void afterApplyInformationToEditor(TextEditorHighlightingPass pass, FileEditor fileEditor, ProgressIndicator updateProgress);
 
   public List<TextEditorHighlightingPass> getAllSubmittedPasses() {
-    ArrayList<TextEditorHighlightingPass> result = new ArrayList<TextEditorHighlightingPass>(mySubmittedPasses.size());
+    List<TextEditorHighlightingPass> result = new ArrayList<TextEditorHighlightingPass>(mySubmittedPasses.size());
     for (ScheduledPass scheduledPass : mySubmittedPasses.keySet()) {
       if (!scheduledPass.myUpdateProgress.isCanceled()) {
         result.add(scheduledPass.myPass);
       }
     }
+    ContainerUtil.quickSort(result, new Comparator<TextEditorHighlightingPass>() {
+      @Override
+      public int compare(TextEditorHighlightingPass o1, TextEditorHighlightingPass o2) {
+        return o1.getId() - o2.getId();
+      }
+    });
     return result;
   }
 
index 5c1dcee7ad6fed43b809520635c4abb267f22a99..50de6483ff243d866b3e92b44c238ed4c697d7aa 100644 (file)
@@ -19,13 +19,19 @@ package com.intellij.codeInsight.daemon.impl;
 import com.intellij.codeHighlighting.TextEditorHighlightingPass;
 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
 import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.impl.EditorMarkupModelImpl;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiFile;
+import com.intellij.util.Alarm;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import javax.swing.*;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -35,14 +41,15 @@ public abstract class ProgressableTextEditorHighlightingPass extends TextEditorH
   private volatile boolean myFinished;
   private volatile long myProgessLimit = 0;
   private final AtomicLong myProgressCount = new AtomicLong();
-  private final Icon myInProgressIcon;
   private final String myPresentableName;
   protected final PsiFile myFile;
 
-  protected ProgressableTextEditorHighlightingPass(final Project project, @Nullable final Document document, final Icon inProgressIcon,
-                                                   final String presentableName, @NotNull PsiFile file, boolean runIntentionPassAfter) {
+  protected ProgressableTextEditorHighlightingPass(@NotNull Project project,
+                                                   @Nullable final Document document,
+                                                   @NotNull String presentableName,
+                                                   @NotNull PsiFile file,
+                                                   boolean runIntentionPassAfter) {
     super(project, document, runIntentionPassAfter);
-    myInProgressIcon = inProgressIcon;
     myPresentableName = presentableName;
     myFile = file;
   }
@@ -50,6 +57,7 @@ public abstract class ProgressableTextEditorHighlightingPass extends TextEditorH
   public final void doCollectInformation(final ProgressIndicator progress) {
     myFinished = false;
     collectInformationWithProgress(progress);
+    repaintTrafficIcon();
   }
 
   protected abstract void collectInformationWithProgress(final ProgressIndicator progress);
@@ -59,6 +67,7 @@ public abstract class ProgressableTextEditorHighlightingPass extends TextEditorH
     applyInformationWithProgress();
     DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(myProject);
     ((DaemonCodeAnalyzerImpl)daemonCodeAnalyzer).getFileStatusMap().markFileUpToDate(myDocument, myFile, getId());
+    repaintTrafficIcon();
   }
 
   protected abstract void applyInformationWithProgress();
@@ -69,18 +78,22 @@ public abstract class ProgressableTextEditorHighlightingPass extends TextEditorH
    */
   public double getProgress() {
     if (myProgessLimit == 0) return -1;
-    return (double)myProgressCount.get() / myProgessLimit;
+    return ((double)myProgressCount.get()) / myProgessLimit;
   }
 
-  public boolean isFinished() {
-    return myFinished;
+  public long getProgressLimit() {
+    return myProgessLimit;
+  }
+
+  public long getProgressCount() {
+    return myProgressCount.get();
   }
 
-  protected final Icon getInProgressIcon() {
-    return myInProgressIcon;
+  public boolean isFinished() {
+    return myFinished;
   }
 
-  protected final String getPresentableName() {
+  protected String getPresentableName() {
     return myPresentableName;
   }
 
@@ -88,12 +101,44 @@ public abstract class ProgressableTextEditorHighlightingPass extends TextEditorH
     myProgessLimit = limit;
   }
 
-  public void advanceProgress(int delta) {
-    myProgressCount.addAndGet(delta);
+  private final Alarm repaintIconAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
+  public void advanceProgress(long delta) {
+    long l = myProgressCount.addAndGet(delta);
+    repaintTrafficIcon();
   }
 
+  private void repaintTrafficIcon() {
+    if (repaintIconAlarm.getActiveRequestCount() == 0 || getProgressCount() >= getProgressLimit()) {
+      repaintIconAlarm.addRequest(new Runnable() {
+        public void run() {
+          if (myProject.isDisposed()) return;
+          Editor editor = getEditorForFile(myFile);
+          if (editor == null || editor.isDisposed()) return;
+          EditorMarkupModelImpl markup = (EditorMarkupModelImpl)editor.getMarkupModel();
+          markup.repaintTrafficLightIcon();
+        }
+      }, 50, null);
+    }
+  }
+
+  private static Editor getEditorForFile(@NotNull final PsiFile psiFile) {
+    VirtualFile virtualFile = psiFile.getVirtualFile();
+    if (virtualFile == null) {
+      PsiFile originalFile = psiFile.getOriginalFile();
+      virtualFile = originalFile.getVirtualFile();
+      if (virtualFile == null) return null;
+    }
+    final FileEditor[] editors = FileEditorManager.getInstance(psiFile.getProject()).getEditors(virtualFile);
+    for (FileEditor editor : editors) {
+      if (editor instanceof TextEditor) {
+        return ((TextEditor)editor).getEditor();
+      }
+    }
+    return null;
+  }
+  
   public static class EmptyPass extends TextEditorHighlightingPass {
-    public EmptyPass(final Project project, @Nullable final Document document, Icon icon, String text) {
+    public EmptyPass(final Project project, @Nullable final Document document) {
       super(project, document, false);
     }
 
index 56be391719cac3f5cb588205f19116bf0a467686..17a1e18672c7d2b3f0b5728135ec47be78ee6f80 100644 (file)
@@ -46,6 +46,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
   private static final Icon IN_PROGRESS_ICON = IconLoader.getIcon("/general/errorsInProgress.png");
   private static final Icon NO_ANALYSIS_ICON = IconLoader.getIcon("/general/noAnalysis.png");
   private static final Icon NO_ICON = new EmptyIcon(IN_PROGRESS_ICON.getIconWidth(), IN_PROGRESS_ICON.getIconHeight());
+  private static final Icon STARING_EYE_ICON = IconLoader.getIcon("/general/inspectionInProgress.png");
 
   private final Project myProject;
   private final Document myDocument;
@@ -57,34 +58,26 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
   @NonNls private static final String BR = "<br>";
   @NonNls private static final String NO_PASS_FOR_MESSAGE_KEY_SUFFIX = ".for";
 
+  public TrafficLightRenderer(Project project, DaemonCodeAnalyzerImpl highlighter, Document document, PsiFile file) {
+    myProject = project;
+    myDaemonCodeAnalyzer = highlighter;
+    myDocument = document;
+    myFile = file;
+  }
+
   public static class DaemonCodeAnalyzerStatus {
     public boolean errorAnalyzingFinished; // all passes done
-    
-    public static class PassStatus {
-      private final String name;
-      private final double progress;
-      private final boolean finished;
-      public Icon inProgressIcon;
-
-      public PassStatus(final String name, final double progress, final boolean finished, Icon inProgressIcon) {
-        this.name = name;
-        this.progress = progress;
-        this.finished = finished;
-        this.inProgressIcon = inProgressIcon;
-      }
-    }
-    public List<PassStatus> passStati = new ArrayList<PassStatus>(); 
-
+    public final List<ProgressableTextEditorHighlightingPass> passStati = new ArrayList<ProgressableTextEditorHighlightingPass>();
     public String[/*rootsNumber*/] noHighlightingRoots;
     public String[/*rootsNumber*/] noInspectionRoots;
-    public int[] errorCount;
-    public int rootsNumber;
+    public int[] errorCount = ArrayUtil.EMPTY_INT_ARRAY;
 
+    public int rootsNumber;
     public String toString() {
       @NonNls String s = "DS: finished=" + errorAnalyzingFinished;
       s += "; pass statuses: " + passStati.size() + "; ";
-      for (PassStatus passStatus : passStati) {
-        s += String.format("(%s %2.0f%% %b)", passStatus.name, passStatus.progress*100, passStatus.finished);
+      for (ProgressableTextEditorHighlightingPass passStatus : passStati) {
+        s += String.format("(%s %2.0f%% %b)", passStatus.getPresentableName(), passStatus.getProgress() *100, passStatus.isFinished());
       }
       return s;
     }
@@ -94,8 +87,8 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
   protected DaemonCodeAnalyzerStatus getDaemonCodeAnalyzerStatus(boolean fillErrorsCount) {
     if (myFile == null || myProject.isDisposed() || !myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) return null;
 
-    ArrayList<String> noInspectionRoots = new ArrayList<String>();
-    ArrayList<String> noHighlightingRoots = new ArrayList<String>();
+    List<String> noInspectionRoots = new ArrayList<String>();
+    List<String> noHighlightingRoots = new ArrayList<String>();
     final PsiFile[] roots = myFile.getPsiRoots();
     for (PsiFile file : roots) {
       if (!HighlightLevelUtil.shouldHighlight(file)) {
@@ -112,29 +105,26 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
     final SeverityRegistrar severityRegistrar = SeverityRegistrar.getInstance(myProject);
     status.errorCount = new int[severityRegistrar.getSeveritiesCount()];
     status.rootsNumber = roots.length;
-    fillDaemonCodeAnalyzerErrorsStatus(status, fillErrorsCount);
-    List<TextEditorHighlightingPass> passes = myDaemonCodeAnalyzer.getPassesToShowProgressFor(myFile);
-    ArrayList<DaemonCodeAnalyzerStatus.PassStatus> passStati = new ArrayList<DaemonCodeAnalyzerStatus.PassStatus>();
+    fillDaemonCodeAnalyzerErrorsStatus(status, fillErrorsCount, severityRegistrar);
+    List<TextEditorHighlightingPass> passes = myDaemonCodeAnalyzer.getPassesToShowProgressFor(myDocument);
     for (TextEditorHighlightingPass tepass : passes) {
       if (!(tepass instanceof ProgressableTextEditorHighlightingPass)) continue;
       ProgressableTextEditorHighlightingPass pass = (ProgressableTextEditorHighlightingPass)tepass;
 
-      double progress = pass.getProgress();
-      if (progress < 0) continue;
-      DaemonCodeAnalyzerStatus.PassStatus passStatus = new DaemonCodeAnalyzerStatus.PassStatus(pass.getPresentableName(), progress, pass.isFinished(), pass.getInProgressIcon());
-      passStati.add(passStatus);
+      if (pass.getProgress() < 0) continue;
+      status.passStati.add(pass);
     }
-    status.passStati = passStati;
     status.errorAnalyzingFinished = myDaemonCodeAnalyzer.isAllAnalysisFinished(myFile);
 
     return status;
   }
 
-  protected void fillDaemonCodeAnalyzerErrorsStatus(final DaemonCodeAnalyzerStatus status, final boolean fillErrorsCount) {
-    final SeverityRegistrar severityRegistrar = SeverityRegistrar.getInstance(myProject);
+  protected void fillDaemonCodeAnalyzerErrorsStatus(final DaemonCodeAnalyzerStatus status,
+                                                    final boolean fillErrorsCount,
+                                                    final SeverityRegistrar severityRegistrar) {
     if (fillErrorsCount) Arrays.fill(status.errorCount, 0);
     final int count = severityRegistrar.getSeveritiesCount() - 1;
-    final HighlightSeverity maxSeverity = severityRegistrar.getSeverityByIndex(count);
+    final HighlightSeverity maxPossibleSeverity = severityRegistrar.getSeverityByIndex(count);
     final HighlightSeverity[] maxFoundSeverity = {null};
 
     DaemonCodeAnalyzerImpl.processHighlights(myDocument, myProject, null, 0, myDocument.getTextLength(), new Processor<HighlightInfo>() {
@@ -147,7 +137,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
           }
         }
         else {
-          if (infoSeverity == maxSeverity) {
+          if (infoSeverity == maxPossibleSeverity) {
             status.errorCount[count] = 1;
             return false;
           }
@@ -164,57 +154,12 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
         status.errorCount[severityIdx] = 1;
       }
     }
-
-    //if (highlights == null) highlights = Arrays.asList(HighlightInfo.EMPTY_ARRAY);
-    //if (fillErrorsCount) {
-    //  highlights = new ArrayList<HighlightInfo>(highlights);
-    //  Collections.sort(highlights, new Comparator<HighlightInfo>() {
-    //    public int compare(HighlightInfo o1, HighlightInfo o2) {
-    //      return o1.getSeverity().myVal - o2.getSeverity().myVal;
-    //    }
-    //  });
-    //  Arrays.fill(status.errorCount, 0);
-    //  for (HighlightInfo highlight : highlights) {
-    //    final HighlightSeverity severity = highlight.getSeverity();
-    //    final int severityIdx = severityRegistrar.getSeverityIdx(severity);
-    //    if (severityIdx != -1) {
-    //      status.errorCount[severityIdx] ++;
-    //    }
-    //  }
-    //}
-    //else {
-    //  HighlightSeverity severity = null;
-    //  final int count = severityRegistrar.getSeveritiesCount() - 1;
-    //  HighlightSeverity maxSeverity = severityRegistrar.getSeverityByIndex(count);
-    //  for (HighlightInfo info : highlights) {
-    //    if (info.getSeverity() == maxSeverity) {
-    //      status.errorCount[count] = 1;
-    //      return;
-    //    }
-    //    if (severity == null || severityRegistrar.compare(severity, info.getSeverity()) <= 0) {
-    //      severity = info.getSeverity();
-    //    }
-    //  }
-    //  if (severity != null) {
-    //    final int severityIdx = severityRegistrar.getSeverityIdx(severity);
-    //    if (severityIdx != -1) {
-    //      status.errorCount[severityIdx] = 1;
-    //    }
-    //  }
-    //}
   }
 
   public final Project getProject() {
     return myProject;
   }
 
-  public TrafficLightRenderer(Project project, DaemonCodeAnalyzerImpl highlighter, Document document, PsiFile file) {
-    myProject = project;
-    myDaemonCodeAnalyzer = highlighter;
-    myDocument = document;
-    myFile = file;
-  }
-
   public String getTooltipMessage() {
     DaemonCodeAnalyzerStatus status = getDaemonCodeAnalyzerStatus(true);
 
@@ -237,9 +182,9 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
     else {
       text += DaemonBundle.message("performing.code.analysis");
       text += "<table>";
-      for (DaemonCodeAnalyzerStatus.PassStatus passStatus : status.passStati) {
-        if (passStatus.finished) continue;
-        text += "<tr><td>" + passStatus.name + ":</td><td>" + renderProgressHtml(passStatus.progress) +  "</td></tr>";
+      for (ProgressableTextEditorHighlightingPass passStatus : status.passStati) {
+        if (passStatus.isFinished()) continue;
+        text += "<tr><td>" + passStatus.getPresentableName() + ":</td><td>" + renderProgressHtml(passStatus.getProgress()) +  "</td></tr>";
       }
       text += "</table>";
     }
@@ -290,13 +235,10 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
   }
 
   private static String getMessageByRoots(String [] roots, int rootsNumber, @NonNls String prefix){
-    if (roots != null) {
-      final int length = roots.length;
-      if (length > 0){
-        return BR + (rootsNumber > 1
-               ? DaemonBundle.message(prefix + NO_PASS_FOR_MESSAGE_KEY_SUFFIX, StringUtil.join(roots, ", "))
-               : DaemonBundle.message(prefix));
-      }
+    if (roots != null && roots.length > 0) {
+      return BR + (rootsNumber > 1
+                   ? DaemonBundle.message(prefix + NO_PASS_FOR_MESSAGE_KEY_SUFFIX, StringUtil.join(roots, ", "))
+                   : DaemonBundle.message(prefix));
     }
     return "";
   }
@@ -318,18 +260,12 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
     if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
       return NO_ANALYSIS_ICON;
     }
-    Icon inProgressMask = null;
+
     boolean atLeastOnePassFinished = status.errorAnalyzingFinished;
-    for (DaemonCodeAnalyzerStatus.PassStatus passStatus : status.passStati) {
-      atLeastOnePassFinished |= passStatus.finished;
-      if (!passStatus.finished) {
-        Icon progressIcon = passStatus.inProgressIcon;
-        if (progressIcon != null) {
-          inProgressMask = inProgressMask == null ? progressIcon : LayeredIcon.create(inProgressMask, progressIcon);
-        }
-      }
+    for (ProgressableTextEditorHighlightingPass passStatus : status.passStati) {
+      atLeastOnePassFinished |= passStatus.isFinished();
     }
-    Icon icon = status.errorAnalyzingFinished ? HighlightDisplayLevel.DO_NOT_SHOW.getIcon() : IN_PROGRESS_ICON;
+    Icon icon = HighlightDisplayLevel.DO_NOT_SHOW.getIcon();
     if (atLeastOnePassFinished) {
       SeverityRegistrar severityRegistrar = SeverityRegistrar.getInstance(myProject);
       for (int i = status.errorCount.length - 1; i >= 0; i--) {
@@ -340,9 +276,20 @@ public class TrafficLightRenderer implements ErrorStripeRenderer {
       }
     }
 
-    if (inProgressMask != null) {
-      icon = LayeredIcon.create(icon, inProgressMask);
+    if (status.errorAnalyzingFinished) return icon;
+      //icon = HighlightDisplayLevel.createIconByMask(Color.blue);
+    double progress = getOverallProgress(status);
+    TruncatingIcon trunc = new TruncatingIcon(icon, (int)(icon.getIconWidth() * progress), (int)(icon.getIconHeight() * progress));
+    return LayeredIcon.create(trunc, STARING_EYE_ICON);
+  }
+
+  private static double getOverallProgress(DaemonCodeAnalyzerStatus status) {
+    long advancement = 0;
+    long limit = 0;
+    for (ProgressableTextEditorHighlightingPass ps : status.passStati) {
+      advancement += ps.getProgressCount();
+      limit += ps.getProgressLimit();
     }
-    return icon;
+    return limit == 0 ? status.errorAnalyzingFinished ? 1 : 0 : advancement * 1.0 / limit;
   }
 }
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
new file mode 100644 (file)
index 0000000..591a50c
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2000-2010 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.codeInsight.daemon.impl;
+
+import com.intellij.codeInsight.daemon.DaemonBundle;
+import com.intellij.codeInsight.hint.LineTooltipRenderer;
+import com.intellij.ide.PowerSaveMode;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.VerticalFlowLayout;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.util.containers.hash.LinkedHashMap;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * User: cdr
+ */
+public class TrafficProgressPanel extends JPanel {
+  private final JLabel statistics = new JLabel();
+  private final Map<ProgressableTextEditorHighlightingPass, Pair<JProgressBar, JLabel>> passes = new LinkedHashMap<ProgressableTextEditorHighlightingPass, Pair<JProgressBar, JLabel>>();
+  private final JLabel statusLabel = new JLabel();
+  private final TrafficLightRenderer myTrafficLightRenderer;
+  private final JPanel passStatuses = new JPanel();
+
+  public TrafficProgressPanel(TrafficLightRenderer trafficLightRenderer, Editor editor) {
+    super(new VerticalFlowLayout());
+    myTrafficLightRenderer = trafficLightRenderer;
+
+    LineTooltipRenderer.setColors(this);
+    LineTooltipRenderer.setBorder(this);
+    LineTooltipRenderer.setColors(passStatuses);
+
+    add(statusLabel);
+    TrafficLightRenderer.DaemonCodeAnalyzerStatus fakeStatusLargeEnough = new TrafficLightRenderer.DaemonCodeAnalyzerStatus();
+    fakeStatusLargeEnough.errorCount = new int[]{1,1,1,1};
+    Project project = trafficLightRenderer.getProject();
+    PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+    for (int i=0; i<3;i++) {
+      fakeStatusLargeEnough.passStati.add(new ProgressableTextEditorHighlightingPass(project, null, DaemonBundle.message("pass.wolf"), psiFile, false) {
+        @Override
+        protected void collectInformationWithProgress(ProgressIndicator progress) {
+        }
+
+        @Override
+        protected void applyInformationWithProgress() {
+        }
+      });
+    }
+    rebuildPassesPanel(fakeStatusLargeEnough);
+    for (Pair<JProgressBar, JLabel> pair : passes.values()) {
+      JProgressBar bar = pair.first;
+      bar.setMaximum(100);
+      JLabel label = pair.second;
+      label.setText("100%");
+    }
+    add(passStatuses);
+
+    add(statistics);
+    updatePanel(fakeStatusLargeEnough);
+  }
+
+  private void rebuildPassesPanel(TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
+    passStatuses.removeAll();
+    passStatuses.setLayout(new GridLayoutManager(Math.max(status.passStati.size(),1), 3));
+    passes.clear();
+    GridConstraints constraints = new GridConstraints();
+    for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
+      JLabel label = new JLabel(pass.getPresentableName() + ":");
+      JProgressBar progressBar = new JProgressBar(0,100);
+      JLabel percLabel = new JLabel();
+      passes.put(pass, Pair.create(progressBar, percLabel));
+      constraints.setColumn(0); passStatuses.add(label, constraints);
+      constraints.setColumn(1); passStatuses.add(progressBar, constraints);
+      constraints.setColumn(2); passStatuses.add(percLabel, constraints);
+      constraints.setRow(constraints.getRow()+1);
+    }
+  }
+
+  public void updatePanel(TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
+    if (status == null) return;
+    if (PowerSaveMode.isEnabled()) {
+      statusLabel.setText("Code analysis is disabled in power save mode.");
+      passStatuses.setVisible(false);
+      statistics.setText("");
+      return;
+    }
+    if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
+      statusLabel.setText(DaemonBundle.message("analysis.hasnot.been.run"));
+      passStatuses.setVisible(false);
+      statistics.setText("");
+      return;
+    }
+
+    if (status.errorAnalyzingFinished) {
+      statusLabel.setText(DaemonBundle.message("analysis.completed"));
+      passStatuses.setVisible(false);
+    }
+    else {
+      statusLabel.setText(DaemonBundle.message("performing.code.analysis"));
+      passStatuses.setVisible(true);
+
+      if (!status.passStati.equals(new ArrayList<ProgressableTextEditorHighlightingPass>(passes.keySet()))) {
+        // passes set has changed
+        rebuildPassesPanel(status);
+      }
+
+      for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
+        double progress = pass.getProgress();
+        Pair<JProgressBar, JLabel> pair = passes.get(pass);
+        JProgressBar progressBar = pair.first;
+        int percent = (int)Math.round(progress * 100);
+        progressBar.setValue(percent);
+        JLabel percentage = pair.second;
+        percentage.setText(percent + "%");
+      }
+    }
+
+    int currentSeverityErrors = 0;
+    String text = "<html><body>";
+    for (int i = status.errorCount.length - 1; i >= 0; i--) {
+      if (status.errorCount[i] > 0) {
+        final HighlightSeverity severity = SeverityRegistrar.getInstance(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
+        String name = status.errorCount[i] > 1 ? StringUtil.pluralize(severity.toString().toLowerCase()) : severity.toString().toLowerCase();
+        text +=  status.errorAnalyzingFinished
+                ? DaemonBundle.message("errors.found", status.errorCount[i], name)
+                : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
+        text += "<br>";
+        currentSeverityErrors += status.errorCount[i];
+      }
+    }
+    if (currentSeverityErrors == 0) {
+      text += status.errorAnalyzingFinished
+              ? DaemonBundle.message("no.errors.or.warnings.found")
+              : DaemonBundle.message("no.errors.or.warnings.found.so.far") + "<br>";
+    }
+    statistics.setText(text);
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficTooltipRendererImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficTooltipRendererImpl.java
new file mode 100644 (file)
index 0000000..5363c70
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2010 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.codeInsight.daemon.impl;
+
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.hint.HintManagerImpl;
+import com.intellij.codeInsight.hint.LineTooltipRenderer;
+import com.intellij.codeInsight.hint.TooltipGroup;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.impl.EditorMarkupModelImpl;
+import com.intellij.openapi.editor.impl.TrafficTooltipRenderer;
+import com.intellij.ui.LightweightHint;
+
+import java.awt.*;
+
+/**
+ * User: cdr
+ */
+public class TrafficTooltipRendererImpl implements TrafficTooltipRenderer {
+  private TrafficProgressPanel myPanel;
+  private final Runnable onHide;
+  private TrafficLightRenderer myTrafficLightRenderer;
+
+  public TrafficTooltipRendererImpl(Runnable onHide) {
+    this.onHide = onHide;
+  }
+
+  @Override
+  public void repaintTooltipWindow() {
+    if (myPanel != null) {
+      myPanel.updatePanel(myTrafficLightRenderer.getDaemonCodeAnalyzerStatus(true));
+    }
+  }
+
+  @Override
+  public LightweightHint show(Editor editor, Point p, boolean alignToRight, TooltipGroup group) {
+    myTrafficLightRenderer = (TrafficLightRenderer)((EditorMarkupModelImpl)editor.getMarkupModel()).getErrorStripeRenderer();
+    myPanel = new TrafficProgressPanel(myTrafficLightRenderer, editor);
+    LineTooltipRenderer.correctLocation(editor, myPanel, p, alignToRight, false, -1);
+    LightweightHint hint = new LightweightHint(myPanel) {
+      @Override
+      public void hide() {
+        if (myPanel == null) return; //double hide?
+        super.hide();
+        myPanel = null;
+        onHide.run();
+      }
+    };
+    HintManagerImpl hintManager = (HintManagerImpl)HintManager.getInstance();
+    hintManager.showEditorHint(hint, editor, p,
+                               HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_OTHER_HINT |
+                               HintManager.HIDE_BY_SCROLLING, 0, false);
+    repaintTooltipWindow();
+    return hint;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return obj.getClass() == getClass() && myTrafficLightRenderer == ((TrafficTooltipRendererImpl)obj).myTrafficLightRenderer;
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TruncatingIcon.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TruncatingIcon.java
new file mode 100644 (file)
index 0000000..0b58cfa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2010 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.codeInsight.daemon.impl;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * User: cdr
+ */
+public class TruncatingIcon implements Icon {
+  private final int myWidth;
+  private final int myHeight;
+  private final Icon myDelegate;
+
+  public TruncatingIcon(Icon delegate, int width, int height) {
+    myDelegate = delegate;
+    myWidth = width;
+    myHeight = height;
+  }
+
+  public void paintIcon(Component c, Graphics g, int x, int y) {
+    Shape old = g.getClip();
+    g.clipRect(x, y, myWidth, myHeight);
+    myDelegate.paintIcon(c, g, x, y);
+    g.setClip(old);
+  }
+
+  public int getIconWidth() {
+    return myWidth;
+  }
+
+  public int getIconHeight() {
+    return myHeight;
+  }
+}
+
index cbfdac182a4e20c7ec127a83832fb28eb5cb4899..c77f7236f3e34a1f1c48e4acac4266a3cb6ccdd7 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.codeHighlighting.Pass;
 import com.intellij.codeHighlighting.TextEditorHighlightingPass;
 import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
 import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
+import com.intellij.codeInsight.daemon.DaemonBundle;
 import com.intellij.codeInspection.LocalInspectionTool;
 import com.intellij.codeInspection.ex.InspectionProfileWrapper;
 import com.intellij.openapi.Disposable;
@@ -100,6 +101,11 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
         return result;
       }
 
+      @Override
+      protected String getPresentableName() {
+        return DaemonBundle.message("pass.whole.inspections");
+      }
+
       void inspectInjectedPsi(PsiElement[] elements, List<LocalInspectionTool> tools) {
         // inspected in LIP already
       }
index c32f89be1dff137182384a5c9c50f1f91e19b80f..33a317280c3a7fc5cbbfe5eb4fc4c23edc2ec00a 100644 (file)
@@ -31,7 +31,7 @@ import org.jetbrains.annotations.NotNull;
 */
 class WolfHighlightingPass extends ProgressableTextEditorHighlightingPass implements DumbAware {
   WolfHighlightingPass(@NotNull Project project, @NotNull Document document, @NotNull PsiFile file) {
-    super(project, document, null, DaemonBundle.message("pass.wolf"), file, false);
+    super(project, document, DaemonBundle.message("pass.wolf"), file, false);
   }
 
   protected void collectInformationWithProgress(final ProgressIndicator progress) {
index 5a85b0f611832894544defac2278e6f1f2775944..13b505597f6137bf94b734fb78da7df1c6ec0f4f 100644 (file)
@@ -229,13 +229,15 @@ public class WolfTheProblemSolverImpl extends WolfTheProblemSolver {
   public void startCheckingIfVincentSolvedProblemsYet(final ProgressIndicator progress, ProgressableTextEditorHighlightingPass pass) throws ProcessCanceledException{
     if (!myProject.isOpen()) return;
 
-    int size;
     List<VirtualFile> files;
     synchronized (myCheckingQueue) {
       files = new ArrayList<VirtualFile>(myCheckingQueue);
-      size = files.size();
     }
-    pass.setProgressLimit(size);
+    long progressLimit = 0;
+    for (VirtualFile file : files) {
+      progressLimit += file.getLength(); // (rough approx number of PSI elements = file length/2) * (visitor count = 2 usually)
+    }
+    pass.setProgressLimit(progressLimit);
     final StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject);
     String oldInfo = saveStatusBarInfo(statusBar);
     try {
@@ -244,13 +246,14 @@ public class WolfTheProblemSolverImpl extends WolfTheProblemSolver {
         if (virtualFile == null) break;
         ApplicationManager.getApplication().invokeLater(new Runnable() {
           public void run() {
+            if (progress.isCanceled()) return;
             statusBar.setInfo("Checking '" + virtualFile.getPresentableUrl() + "'");
           }
         });
         if (!virtualFile.isValid() || orderVincentToCleanTheCar(virtualFile, progress)) {
           doRemove(virtualFile);
         }
-        pass.advanceProgress(1);
+        pass.advanceProgress(virtualFile.getLength());
       }
     }
     finally {
index e6ed3096f99f6e11cb9b2971f7e11fc441d08644..a5283a871c959b360cd664f8ea827b6a32805f57 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.openapi.actionSystem.IdeActions;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.LightweightHint;
@@ -63,57 +64,14 @@ public class LineTooltipRenderer implements TooltipRenderer {
     myText = myText.replaceAll(String.valueOf(UIUtil.MNEMONIC), "");
     final boolean expanded = myCurrentWidth > 0 && dressDescription(editor);
 
-    //pane
-    final JEditorPane pane = initPane(myText);
-    pane.setCaretPosition(0);
     final HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
     final JComponent contentComponent = editor.getContentComponent();
 
-    final JComponent editorComponent = editor.getComponent();
-    final JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();
-
-    int widthLimit = layeredPane.getWidth() - 10;
-    int heightLimit = layeredPane.getHeight() - 5;
+    final JEditorPane pane = initPane(myText);
+    correctLocation(editor, pane, p, alignToRight, expanded, myCurrentWidth);
 
     final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(pane);
     scrollPane.setBorder(null);
-    int width = expanded ? 3 * myCurrentWidth / 2 : pane.getPreferredSize().width;
-    int height = expanded ? Math.max(pane.getPreferredSize().height, 150) : pane.getPreferredSize().height;
-
-    if (alignToRight) {
-      p.x = Math.max(0, p.x - width);
-    }
-
-    // try to make cursor outside tooltip. SCR 15038
-    p.x += 3;
-    p.y += 3;
-
-    if (p.x >= widthLimit - width) {
-      p.x = widthLimit - width;
-      width = Math.min(width, widthLimit);
-      height += 20;
-    }
-
-    if (p.x < 3) {
-      p.x = 3;
-    }
-
-    if (p.y > heightLimit - height) {
-      p.y = heightLimit - height;
-      height = Math.min(heightLimit, height);
-    }
-
-    if (p.y < 3) {
-      p.y = 3;
-    }
-
-    locateOutsideMouseCursor(editor, layeredPane, p, width, height, heightLimit);
-
-    // in order to restrict tooltip size
-    pane.setSize(width, height);
-    pane.setMaximumSize(new Dimension(width, height));
-    pane.setMinimumSize(new Dimension(width, height));
-    pane.setPreferredSize(new Dimension(width, height));
 
     scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
     scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
@@ -193,11 +151,79 @@ public class LineTooltipRenderer implements TooltipRenderer {
     });
 
     hintManager.showEditorHint(hint, editor, p,
-                               HintManagerImpl.HIDE_BY_ANY_KEY | HintManagerImpl.HIDE_BY_TEXT_CHANGE | HintManagerImpl.HIDE_BY_OTHER_HINT |
-                               HintManagerImpl.HIDE_BY_SCROLLING, 0, false);
+                               HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_OTHER_HINT |
+                               HintManager.HIDE_BY_SCROLLING, 0, false);
     return hint;
   }
 
+  public static void correctLocation(Editor editor,
+                                     JComponent tooltipComponent,
+                                     Point p,
+                                     boolean alignToRight,
+                                     boolean expanded,
+                                     int currentWidth) {
+    final JComponent editorComponent = editor.getComponent();
+    final JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();
+
+    int widthLimit = layeredPane.getWidth() - 10;
+    int heightLimit = layeredPane.getHeight() - 5;
+
+    Dimension dimension = correctLocation(editor, p, alignToRight, expanded, tooltipComponent, layeredPane, widthLimit, heightLimit, currentWidth);
+
+    // in order to restrict tooltip size
+    tooltipComponent.setSize(dimension);
+    tooltipComponent.setMaximumSize(dimension);
+    tooltipComponent.setMinimumSize(dimension);
+    tooltipComponent.setPreferredSize(dimension);
+  }
+
+  private static Dimension correctLocation(Editor editor,
+                                           Point p,
+                                           boolean alignToRight,
+                                           boolean expanded,
+                                           JComponent tooltipComponent,
+                                           JLayeredPane layeredPane,
+                                           int widthLimit,
+                                           int heightLimit,
+                                           int currentWidth) {
+    Dimension preferredSize = tooltipComponent.getPreferredSize();
+    int width = expanded ? 3 * currentWidth / 2 : preferredSize.width;
+    int height = expanded ? Math.max(preferredSize.height, 150) : preferredSize.height;
+    Dimension dimension = new Dimension(width, height);
+
+    if (alignToRight) {
+      p.x = Math.max(0, p.x - width);
+    }
+
+    // try to make cursor outside tooltip. SCR 15038
+    p.x += 3;
+    p.y += 3;
+
+    if (p.x >= widthLimit - width) {
+      p.x = widthLimit - width;
+      width = Math.min(width, widthLimit);
+      height += 20;
+      dimension = new Dimension(width, height);
+    }
+
+    if (p.x < 3) {
+      p.x = 3;
+    }
+
+    if (p.y > heightLimit - height) {
+      p.y = heightLimit - height;
+      height = Math.min(heightLimit, height);
+      dimension = new Dimension(width, height);
+    }
+
+    if (p.y < 3) {
+      p.y = 3;
+    }
+
+    locateOutsideMouseCursor(editor, layeredPane, p, width, height, heightLimit);
+    return dimension;
+  }
+
   private static void locateOutsideMouseCursor(Editor editor,
                                                JComponent editorComponent,
                                                Point p,
@@ -237,16 +263,26 @@ public class LineTooltipRenderer implements TooltipRenderer {
     text = "<html><head>" + UIUtil.getCssFontDeclaration(UIUtil.getLabelFont()) + "</head><body>" + getHtmlBody(text) + "</body></html>";
     final JEditorPane pane = new JEditorPane(UIUtil.HTML_MIME, text);
     pane.setEditable(false);
+    setColors(pane);
+    setBorder(pane);
+
+    pane.setCaretPosition(0);
+    return pane;
+  }
+
+  public static void setColors(JComponent pane) {
+    pane.setForeground(Color.black);
+    pane.setBackground(HintUtil.INFORMATION_COLOR);
+    pane.setOpaque(true);
+  }
+
+  public static void setBorder(JComponent pane) {
     pane.setBorder(
       BorderFactory.createCompoundBorder(
         BorderFactory.createLineBorder(Color.black),
         BorderFactory.createEmptyBorder(0, 5, 0, 5)
       )
     );
-    pane.setForeground(Color.black);
-    pane.setBackground(HintUtil.INFORMATION_COLOR);
-    pane.setOpaque(true);
-    return pane;
   }
 
   public void addBelow(String text) {
@@ -284,11 +320,11 @@ public class LineTooltipRenderer implements TooltipRenderer {
 
     final LineTooltipRenderer lineTooltipRenderer = (LineTooltipRenderer)o;
 
-    return myText == null ? lineTooltipRenderer.myText == null : myText.equals(lineTooltipRenderer.myText);
+    return Comparing.strEqual(myText, lineTooltipRenderer.myText);
   }
 
   public int hashCode() {
-    return myText != null ? myText.hashCode() : 0;
+    return myText == null ? 0 : myText.hashCode();
   }
 
   public String getText() {
index f78f9eed9150bc76b90d7367b1f253f272ac9250..97a8b1086c33557c1f83a7eaf7ec75914b45473b 100644 (file)
@@ -20,6 +20,7 @@
 package com.intellij.openapi.editor.ex;
 
 import com.intellij.codeInsight.hint.TooltipRenderer;
+import com.intellij.openapi.editor.impl.TrafficTooltipRenderer;
 import com.intellij.openapi.editor.markup.RangeHighlighter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -31,4 +32,6 @@ public interface ErrorStripTooltipRendererProvider {
   TooltipRenderer calcTooltipRenderer(@NotNull Collection<RangeHighlighter> highlighters);
   TooltipRenderer calcTooltipRenderer(@NotNull String text);
   TooltipRenderer calcTooltipRenderer(@NotNull String text, int width);
+
+  TrafficTooltipRenderer createTrafficTooltipRenderer(Runnable onHide);
 }
\ No newline at end of file
index 81863eb455ab269898bef2732331a8dd65ff2d84..cbbc9f074261d19ce348df75f795498a75bb1e55 100644 (file)
@@ -41,6 +41,7 @@ import com.intellij.openapi.editor.markup.ErrorStripeRenderer;
 import com.intellij.openapi.editor.markup.RangeHighlighter;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.ui.ColorUtil;
+import com.intellij.ui.LightweightHint;
 import com.intellij.ui.PopupHandler;
 import com.intellij.util.Processor;
 import com.intellij.util.ui.ButtonlessScrollBarUI;
@@ -49,6 +50,7 @@ import gnu.trove.THashSet;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
+import javax.swing.plaf.ScrollBarUI;
 import java.awt.*;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
@@ -110,6 +112,14 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
     myEditorSourceHeight = myEditor.getPreferredHeight();
   }
 
+  public void repaintTrafficLightIcon() {
+    MyErrorPanel errorPanel = getErrorPanel();
+    if (errorPanel != null) {
+      errorPanel.myErrorStripeButton.repaint();
+      errorPanel.repaintTrafficTooltip();
+    }
+  }
+
   private static class PositionedStripe {
     private final Color color;
     private final int yStart;
@@ -126,7 +136,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
     }
   }
 
-  public boolean showToolTipByMouseMove(final MouseEvent e, final double width) {
+  private boolean showToolTipByMouseMove(final MouseEvent e, final double width) {
     Set<RangeHighlighter> highlighters = new THashSet<RangeHighlighter>();
 
     getNearestHighlighters(this, e, width, highlighters);
@@ -199,10 +209,15 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
       myEditor.getVerticalScrollBar().setPersistentUI(ButtonlessScrollBarUI.createNormal());
     }
   }
+  private MyErrorPanel getErrorPanel() {
+    ScrollBarUI ui = myEditor.getVerticalScrollBar().getUI();
+    return ui instanceof MyErrorPanel ? (MyErrorPanel)ui : null;
+  }
 
   public void setErrorPanelPopupHandler(@NotNull PopupHandler handler) {
-    if (myEditor.getVerticalScrollBar().getUI() instanceof MyErrorPanel) {
-      ((MyErrorPanel)myEditor.getVerticalScrollBar().getUI()).setPopupHandler(handler);
+    MyErrorPanel errorPanel = getErrorPanel();
+    if (errorPanel != null) {
+      errorPanel.setPopupHandler(handler);
     }
   }
 
@@ -553,10 +568,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
       }
 
       if (e.getY() < buttonHeight && myErrorStripeRenderer != null) {
-        String tooltipMessage = myErrorStripeRenderer.getTooltipMessage();
-        if (tooltipMessage != null) {
-          showTooltip(e, myTooltipRendererProvider.calcTooltipRenderer(tooltipMessage));
-        }
+        showTrafficLightTooltip(e);
         return;
       }
 
@@ -572,6 +584,27 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
       }
     }
 
+    private TrafficTooltipRenderer myTrafficTooltipRenderer;
+    private void showTrafficLightTooltip(MouseEvent e) {
+      //final String tooltipMessage = myErrorStripeRenderer.getTooltipMessage();
+      //if (tooltipMessage == null) return;
+      if (myTrafficTooltipRenderer == null) {
+        myTrafficTooltipRenderer = myTooltipRendererProvider.createTrafficTooltipRenderer(new Runnable() {
+          @Override
+          public void run() {
+            myTrafficTooltipRenderer = null;
+          }
+        });
+      }
+      showTooltip(e, myTrafficTooltipRenderer);
+    }
+
+    private void repaintTrafficTooltip() {
+      if (myTrafficTooltipRenderer != null) {
+        myTrafficTooltipRenderer.repaintTooltipWindow();
+      }
+    }
+
     private void cancelMyToolTips(final MouseEvent e) {
       final TooltipController tooltipController = TooltipController.getInstance();
       if (!tooltipController.shouldSurvive(e)) {
@@ -680,6 +713,27 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
     public TooltipRenderer calcTooltipRenderer(@NotNull final String text, final int width) {
       return new LineTooltipRenderer(text, width);
     }
+
+    @Override
+    public TrafficTooltipRenderer createTrafficTooltipRenderer(final Runnable onHide) {
+      return new TrafficTooltipRenderer() {
+        @Override
+        public void repaintTooltipWindow() {
+        }
+
+        @Override
+        public LightweightHint show(Editor editor, Point p, boolean alignToRight, TooltipGroup group) {
+          JLabel label = new JLabel("WTF");
+          return new LightweightHint(label){
+            @Override
+            public void hide() {
+              super.hide();
+              onHide.run();
+            }
+          };
+        }
+      };
+    }
   }
 
   private int offsetToYPosition(int offset) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/TrafficTooltipRenderer.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/TrafficTooltipRenderer.java
new file mode 100644 (file)
index 0000000..b7b6302
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2010 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.impl;
+
+import com.intellij.codeInsight.hint.TooltipRenderer;
+
+/**
+ * User: cdr
+ */
+public interface TrafficTooltipRenderer extends TooltipRenderer {
+  void repaintTooltipWindow();
+}
index 31c6b173e532c63bbb86194484847f7ddf65f18a..212d3d84b664d76260d1d9b0f442efac5377b67d 100644 (file)
@@ -415,4 +415,7 @@ class TextEditorComponent extends JPanel implements DataProvider{
     }
   }
 
+  public VirtualFile getFile() {
+    return myFile;
+  }
 }
index 20b934c7101e7df726cf79dc20d9f62bf464380c..4c2a81f9275e7b0bb18087895a2ff00401e34131 100644 (file)
@@ -144,4 +144,9 @@ public class TextEditorImpl extends UserDataHolderBase implements TextEditor {
     OpenFileDescriptor d = (OpenFileDescriptor)navigatable;
     d.navigateIn(getEditor());
   }
+
+  @Override
+  public String toString() {
+    return "Editor: "+getComponent().getFile();
+  }
 }
index 82f9ac4ae9019a6fd00f0072dac87f97e582ab37..a66b57918c1a33b9baddfb0f77170ec4eb34c45b 100644 (file)
@@ -20,9 +20,10 @@ no.syntax.highlighting.performed.for=No syntax highlighting performed for {0}.
 # suppress inspection "UnusedProperty"
 no.inspections.performed.for=No inspections performed {0}.
 
-pass.syntax=Syntax
+pass.syntax=Syntax analysis
 pass.inspection=Inspections
-pass.wolf=Checking affected files
+pass.wolf=Checking red files
+pass.whole.inspections=Slow Inspections
 analysis.completed=Analysis completed.
 
 no.errors.or.warnings.found=No errors or warnings found.
index 90ad7cf856866e02ebc20684407c133b55d0f3c8..3b06fbe2420f629c9b1a20371d9ebfe921371f39 100644 (file)
@@ -154,17 +154,16 @@ public class DomElementsErrorPanel extends JPanel implements CommittablePanel, H
       final DaemonCodeAnalyzerStatus status = super.getDaemonCodeAnalyzerStatus(fillErrorsCount);
       if (status != null && isInspectionCompleted()) {
         status.errorAnalyzingFinished = true;
-        for (final DaemonCodeAnalyzerStatus.PassStatus passStatus : status.passStati) {
-          passStatus.inProgressIcon = null;
-        }
       }
       return status;
     }
 
     @Override
-    protected void fillDaemonCodeAnalyzerErrorsStatus(DaemonCodeAnalyzerStatus status, boolean fillErrorsCount) {
+    protected void fillDaemonCodeAnalyzerErrorsStatus(DaemonCodeAnalyzerStatus status,
+                                                      boolean fillErrorsCount,
+                                                      SeverityRegistrar severityRegistrar) {
       for (int i = 0; i < status.errorCount.length; i++) {
-        final HighlightSeverity minSeverity = SeverityRegistrar.getInstance(myProject).getSeverityByIndex(i);
+        final HighlightSeverity minSeverity = severityRegistrar.getSeverityByIndex(i);
         if (minSeverity == null) {
           continue;
         }