0d6ecb2b56356c17daa8049dc6119b85ab7059f7
[idea/community.git] / platform / lang-impl / src / com / intellij / codeInsight / daemon / impl / TrafficProgressPanel.java
1 /*
2  * Copyright 2000-2010 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.codeInsight.daemon.impl;
17
18 import com.intellij.codeInsight.daemon.DaemonBundle;
19 import com.intellij.codeInsight.hint.LineTooltipRenderer;
20 import com.intellij.ide.PowerSaveMode;
21 import com.intellij.lang.annotation.HighlightSeverity;
22 import com.intellij.openapi.editor.Editor;
23 import com.intellij.openapi.progress.ProgressIndicator;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.ui.VerticalFlowLayout;
26 import com.intellij.openapi.util.Pair;
27 import com.intellij.openapi.util.text.StringUtil;
28 import com.intellij.psi.PsiDocumentManager;
29 import com.intellij.psi.PsiFile;
30 import com.intellij.ui.HintHint;
31 import com.intellij.uiDesigner.core.GridConstraints;
32 import com.intellij.uiDesigner.core.GridLayoutManager;
33 import com.intellij.util.containers.hash.LinkedHashMap;
34
35 import javax.swing.*;
36 import java.util.ArrayList;
37 import java.util.Map;
38
39 /**
40  * User: cdr
41  */
42 public class TrafficProgressPanel extends JPanel {
43   private final JLabel statistics = new JLabel();
44   private final Map<ProgressableTextEditorHighlightingPass, Pair<JProgressBar, JLabel>> passes = new LinkedHashMap<ProgressableTextEditorHighlightingPass, Pair<JProgressBar, JLabel>>();
45   private final JLabel statusLabel = new JLabel();
46   private final TrafficLightRenderer myTrafficLightRenderer;
47   private final JPanel passStatuses = new JPanel();
48
49   public TrafficProgressPanel(TrafficLightRenderer trafficLightRenderer, Editor editor, HintHint hintHint) {
50     super(new VerticalFlowLayout());
51     myTrafficLightRenderer = trafficLightRenderer;
52
53
54     add(statusLabel);
55     TrafficLightRenderer.DaemonCodeAnalyzerStatus fakeStatusLargeEnough = new TrafficLightRenderer.DaemonCodeAnalyzerStatus();
56     fakeStatusLargeEnough.errorCount = new int[]{1,1,1,1};
57     Project project = trafficLightRenderer.getProject();
58     PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
59     for (int i=0; i<3;i++) {
60       fakeStatusLargeEnough.passStati.add(new ProgressableTextEditorHighlightingPass(project, null, DaemonBundle.message("pass.wolf"), psiFile, false) {
61         @Override
62         protected void collectInformationWithProgress(ProgressIndicator progress) {
63         }
64
65         @Override
66         protected void applyInformationWithProgress() {
67         }
68       });
69     }
70     rebuildPassesPanel(fakeStatusLargeEnough);
71     for (Pair<JProgressBar, JLabel> pair : passes.values()) {
72       JProgressBar bar = pair.first;
73       bar.setMaximum(100);
74       JLabel label = pair.second;
75       label.setText("100%");
76     }
77     add(passStatuses);
78
79     add(statistics);
80     updatePanel(fakeStatusLargeEnough);
81
82     hintHint.initStyle(this, true);
83   }
84
85   private void rebuildPassesPanel(TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
86     passStatuses.removeAll();
87     passStatuses.setLayout(new GridLayoutManager(Math.max(status.passStati.size(),1), 3));
88     passes.clear();
89     GridConstraints constraints = new GridConstraints();
90     for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
91       JLabel label = new JLabel(pass.getPresentableName() + ":");
92       JProgressBar progressBar = new JProgressBar(0,100);
93       JLabel percLabel = new JLabel();
94       passes.put(pass, Pair.create(progressBar, percLabel));
95       constraints.setColumn(0); passStatuses.add(label, constraints);
96       constraints.setColumn(1); passStatuses.add(progressBar, constraints);
97       constraints.setColumn(2); passStatuses.add(percLabel, constraints);
98       constraints.setRow(constraints.getRow()+1);
99     }
100   }
101
102   public void updatePanel(TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
103     if (status == null) return;
104     if (PowerSaveMode.isEnabled()) {
105       statusLabel.setText("Code analysis is disabled in power save mode.");
106       passStatuses.setVisible(false);
107       statistics.setText("");
108       return;
109     }
110     if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
111       statusLabel.setText(DaemonBundle.message("analysis.hasnot.been.run"));
112       passStatuses.setVisible(false);
113       statistics.setText("");
114       return;
115     }
116
117     if (status.errorAnalyzingFinished) {
118       statusLabel.setText(DaemonBundle.message("analysis.completed"));
119       passStatuses.setVisible(false);
120     }
121     else {
122       statusLabel.setText(DaemonBundle.message("performing.code.analysis"));
123       passStatuses.setVisible(true);
124
125       if (!status.passStati.equals(new ArrayList<ProgressableTextEditorHighlightingPass>(passes.keySet()))) {
126         // passes set has changed
127         rebuildPassesPanel(status);
128       }
129
130       for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
131         double progress = pass.getProgress();
132         Pair<JProgressBar, JLabel> pair = passes.get(pass);
133         JProgressBar progressBar = pair.first;
134         int percent = (int)Math.round(progress * 100);
135         progressBar.setValue(percent);
136         JLabel percentage = pair.second;
137         percentage.setText(percent + "%");
138       }
139     }
140
141     int currentSeverityErrors = 0;
142     String text = "<html><body>";
143     for (int i = status.errorCount.length - 1; i >= 0; i--) {
144       if (status.errorCount[i] > 0) {
145         final HighlightSeverity severity = SeverityRegistrar.getInstance(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
146         String name = status.errorCount[i] > 1 ? StringUtil.pluralize(severity.toString().toLowerCase()) : severity.toString().toLowerCase();
147         text +=  status.errorAnalyzingFinished
148                 ? DaemonBundle.message("errors.found", status.errorCount[i], name)
149                 : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
150         text += "<br>";
151         currentSeverityErrors += status.errorCount[i];
152       }
153     }
154     if (currentSeverityErrors == 0) {
155       text += status.errorAnalyzingFinished
156               ? DaemonBundle.message("no.errors.or.warnings.found")
157               : DaemonBundle.message("no.errors.or.warnings.found.so.far") + "<br>";
158     }
159     statistics.setText(text);
160   }
161 }