mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
correct rendering of traffic light
more informative tooltip
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
+6
-46
@@ -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);
|
||||
}
|
||||
|
||||
+6
@@ -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);
|
||||
|
||||
+1
-3
@@ -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;
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -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;
|
||||
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
+13
-20
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+59
-14
@@ -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 long getProgressLimit() {
|
||||
return myProgessLimit;
|
||||
}
|
||||
|
||||
public long getProgressCount() {
|
||||
return myProgressCount.get();
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return myFinished;
|
||||
}
|
||||
|
||||
protected final Icon getInProgressIcon() {
|
||||
return myInProgressIcon;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+49
-102
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+161
@@ -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);
|
||||
}
|
||||
}
|
||||
+74
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
+7
-4
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
+3
@@ -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);
|
||||
}
|
||||
+61
-7
@@ -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) {
|
||||
|
||||
+25
@@ -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();
|
||||
}
|
||||
+3
@@ -415,4 +415,7 @@ class TextEditorComponent extends JPanel implements DataProvider{
|
||||
}
|
||||
}
|
||||
|
||||
public VirtualFile getFile() {
|
||||
return myFile;
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user