Merge remote-tracking branch 'origin/master'
[idea/community.git] / java / compiler / impl / src / com / intellij / compiler / impl / ProblemsViewImpl.java
1 /*
2  * Copyright 2000-2012 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.compiler.impl;
17
18 import com.intellij.compiler.ProblemsView;
19 import com.intellij.icons.AllIcons;
20 import com.intellij.ide.errorTreeView.ErrorTreeElement;
21 import com.intellij.ide.errorTreeView.ErrorTreeElementKind;
22 import com.intellij.ide.errorTreeView.ErrorViewStructure;
23 import com.intellij.ide.errorTreeView.GroupingElement;
24 import com.intellij.openapi.Disposable;
25 import com.intellij.openapi.compiler.CompileScope;
26 import com.intellij.openapi.project.Project;
27 import com.intellij.openapi.util.Disposer;
28 import com.intellij.openapi.util.IconLoader;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.openapi.wm.ToolWindow;
31 import com.intellij.openapi.wm.ToolWindowAnchor;
32 import com.intellij.openapi.wm.ToolWindowManager;
33 import com.intellij.pom.Navigatable;
34 import com.intellij.ui.content.Content;
35 import com.intellij.ui.content.ContentFactory;
36 import com.intellij.util.concurrency.SequentialTaskExecutor;
37 import com.intellij.util.ui.UIUtil;
38 import org.jetbrains.annotations.NotNull;
39 import org.jetbrains.annotations.Nullable;
40 import org.jetbrains.ide.PooledThreadExecutor;
41
42 import javax.swing.*;
43 import java.util.EnumSet;
44 import java.util.UUID;
45
46 /**
47  * @author Eugene Zhuravlev
48  *         Date: 9/18/12
49  */
50 public class ProblemsViewImpl extends ProblemsView{
51   private static final String PROBLEMS_TOOLWINDOW_ID = "Problems";
52   private static final EnumSet<ErrorTreeElementKind> ALL_MESSAGE_KINDS = EnumSet.allOf(ErrorTreeElementKind.class);
53
54   private final ProblemsViewPanel myPanel;
55   private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
56   private final Icon myActiveIcon = AllIcons.Toolwindows.Problems;
57   private final Icon myPassiveIcon = IconLoader.getDisabledIcon(myActiveIcon);
58
59   public ProblemsViewImpl(final Project project, final ToolWindowManager wm) {
60     super(project);
61     myPanel = new ProblemsViewPanel(project);
62     Disposer.register(project, new Disposable() {
63       @Override
64       public void dispose() {
65         Disposer.dispose(myPanel);
66       }
67     });
68     UIUtil.invokeLaterIfNeeded(new Runnable() {
69       @Override
70       public void run() {
71         if (project.isDisposed()) {
72           return;
73         }
74         final ToolWindow tw = wm.registerToolWindow(PROBLEMS_TOOLWINDOW_ID, false, ToolWindowAnchor.BOTTOM, project, true);
75         final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanel, "", false);
76         // todo: setup content?
77         tw.getContentManager().addContent(content);
78         Disposer.register(project, new Disposable() {
79           @Override
80           public void dispose() {
81             tw.getContentManager().removeAllContents(true);
82           }
83         });
84         updateIcon();
85       }
86     });
87   }
88
89   @Override
90   public void clearOldMessages(@Nullable final CompileScope scope, @NotNull final UUID currentSessionId) {
91     myViewUpdater.execute(new Runnable() {
92       @Override
93       public void run() {
94         cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId);
95         updateIcon();
96         myPanel.reload();
97       }
98     });
99   }
100
101   private void cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) {
102     final ErrorViewStructure structure = myPanel.getErrorViewStructure();
103     for (ErrorTreeElement element : structure.getChildElements(fromElement)) {
104       if (element instanceof GroupingElement) {
105         if (scope != null) {
106           final VirtualFile file = ((GroupingElement)element).getFile();
107           if (file != null && !scope.belongs(file.getUrl())) {
108             continue; 
109           }
110         }
111         if (!currentSessionId.equals(element.getData())) {
112           structure.removeElement(element);
113         }
114         else {
115           cleanupChildrenRecursively(element, scope, currentSessionId);
116         }
117       }
118       else {
119         if (!currentSessionId.equals(element.getData())) {
120           structure.removeElement(element);
121         }
122       }
123     }
124   }
125
126   @Override
127   public void addMessage(final int type,
128                          @NotNull final String[] text,
129                          @Nullable final String groupName,
130                          @Nullable final Navigatable navigatable,
131                          @Nullable final String exportTextPrefix, @Nullable final String rendererTextPrefix, @Nullable final UUID sessionId) {
132
133     myViewUpdater.execute(new Runnable() {
134       @Override
135       public void run() {
136         final ErrorViewStructure structure = myPanel.getErrorViewStructure();
137         final GroupingElement group = structure.lookupGroupingElement(groupName);
138         if (group != null && sessionId != null && !sessionId.equals(group.getData())) {
139           structure.removeElement(group);
140         }
141         if (navigatable != null) {
142           myPanel.addMessage(type, text, groupName, navigatable, exportTextPrefix, rendererTextPrefix, sessionId);
143         }
144         else {
145           myPanel.addMessage(type, text, null, -1, -1, sessionId);
146         }
147         updateIcon();
148       }
149     });
150   }
151
152   private void updateIcon() {
153     UIUtil.invokeLaterIfNeeded(new Runnable() {
154       @Override
155       public void run() {
156         if (!myProject.isDisposed()) {
157           final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID);
158           if (tw != null) {
159             final boolean active = myPanel.getErrorViewStructure().hasMessages(ALL_MESSAGE_KINDS);
160             tw.setIcon(active ? myActiveIcon : myPassiveIcon);
161           }
162         }
163       }
164     });
165   }
166
167   @Override
168   public void setProgress(String text, float fraction) {
169     myPanel.setProgress(text, fraction);
170   }
171
172   @Override
173   public void setProgress(String text) {
174     myPanel.setProgressText(text);
175   }
176
177   @Override
178   public void clearProgress() {
179     myPanel.clearProgressData();
180   }
181 }