added "analysis has been suspended" message
[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.ide.PowerSaveMode;
20 import com.intellij.lang.annotation.HighlightSeverity;
21 import com.intellij.openapi.editor.Editor;
22 import com.intellij.openapi.progress.ProgressIndicator;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.ui.VerticalFlowLayout;
25 import com.intellij.openapi.util.Pair;
26 import com.intellij.openapi.util.text.StringUtil;
27 import com.intellij.psi.PsiDocumentManager;
28 import com.intellij.psi.PsiFile;
29 import com.intellij.ui.HintHint;
30 import com.intellij.uiDesigner.core.GridConstraints;
31 import com.intellij.uiDesigner.core.GridLayoutManager;
32 import com.intellij.util.containers.hash.LinkedHashMap;
33
34 import javax.swing.*;
35 import java.util.ArrayList;
36 import java.util.Map;
37
38 /**
39  * User: cdr
40  */
41 public class TrafficProgressPanel extends JPanel {
42   private final JLabel statistics = new JLabel();
43   private final Map<ProgressableTextEditorHighlightingPass, Pair<JProgressBar, JLabel>> passes = new LinkedHashMap<ProgressableTextEditorHighlightingPass, Pair<JProgressBar, JLabel>>();
44   private final JLabel statusLabel = new JLabel();
45   private final TrafficLightRenderer myTrafficLightRenderer;
46   private final JPanel passStatuses = new JPanel();
47
48   public TrafficProgressPanel(TrafficLightRenderer trafficLightRenderer, Editor editor, HintHint hintHint) {
49     super(new VerticalFlowLayout());
50     myTrafficLightRenderer = trafficLightRenderer;
51
52
53     add(statusLabel);
54     TrafficLightRenderer.DaemonCodeAnalyzerStatus fakeStatusLargeEnough = new TrafficLightRenderer.DaemonCodeAnalyzerStatus();
55     fakeStatusLargeEnough.errorCount = new int[]{1,1,1,1};
56     Project project = trafficLightRenderer.getProject();
57     PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
58     fakeStatusLargeEnough.passStati = new ArrayList<ProgressableTextEditorHighlightingPass>();
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.enabled) {
111       statusLabel.setText("Code analysis has been suspended.");
112       passStatuses.setVisible(false);
113       statistics.setText("");
114       return;
115     }
116     if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
117       statusLabel.setText(DaemonBundle.message("analysis.hasnot.been.run"));
118       passStatuses.setVisible(false);
119       statistics.setText("");
120       return;
121     }
122
123     if (status.errorAnalyzingFinished) {
124       statusLabel.setText(DaemonBundle.message("analysis.completed"));
125       passStatuses.setVisible(false);
126     }
127     else {
128       statusLabel.setText(DaemonBundle.message("performing.code.analysis"));
129       passStatuses.setVisible(true);
130
131       if (!status.passStati.equals(new ArrayList<ProgressableTextEditorHighlightingPass>(passes.keySet()))) {
132         // passes set has changed
133         rebuildPassesPanel(status);
134       }
135
136       for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
137         double progress = pass.getProgress();
138         Pair<JProgressBar, JLabel> pair = passes.get(pass);
139         JProgressBar progressBar = pair.first;
140         int percent = (int)Math.round(progress * 100);
141         progressBar.setValue(percent);
142         JLabel percentage = pair.second;
143         percentage.setText(percent + "%");
144       }
145     }
146
147     int currentSeverityErrors = 0;
148     String text = "<html><body>";
149     for (int i = status.errorCount.length - 1; i >= 0; i--) {
150       if (status.errorCount[i] > 0) {
151         final HighlightSeverity severity = SeverityRegistrar.getInstance(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
152         String name = status.errorCount[i] > 1 ? StringUtil.pluralize(severity.toString().toLowerCase()) : severity.toString().toLowerCase();
153         text +=  status.errorAnalyzingFinished
154                 ? DaemonBundle.message("errors.found", status.errorCount[i], name)
155                 : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
156         text += "<br>";
157         currentSeverityErrors += status.errorCount[i];
158       }
159     }
160     if (currentSeverityErrors == 0) {
161       text += status.errorAnalyzingFinished
162               ? DaemonBundle.message("no.errors.or.warnings.found")
163               : DaemonBundle.message("no.errors.or.warnings.found.so.far") + "<br>";
164     }
165     statistics.setText(text);
166   }
167 }