run tests on module classpath: Inspection Gadgets
[idea/community.git] / platform / platform-api / src / com / intellij / util / IconUtil.java
1 /*
2  * Copyright 2000-2009 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.util;
17
18 import com.intellij.ide.FileIconPatcher;
19 import com.intellij.ide.FileIconProvider;
20 import com.intellij.openapi.extensions.Extensions;
21 import com.intellij.openapi.project.DumbAware;
22 import com.intellij.openapi.project.DumbService;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.util.IconLoader;
25 import com.intellij.openapi.util.Iconable;
26 import com.intellij.openapi.util.Key;
27 import com.intellij.openapi.vfs.VirtualFile;
28 import com.intellij.ui.IconDeferrer;
29 import com.intellij.ui.RowIcon;
30 import com.intellij.ui.LayeredIcon;
31 import com.intellij.util.ui.EmptyIcon;
32 import org.jetbrains.annotations.Nullable;
33
34 import javax.swing.*;
35
36
37 public class IconUtil {
38
39   private IconUtil() {
40   }
41
42   private static class FileIconKey {
43     private final VirtualFile myFile;
44     private final Project myProject;
45     private final int myFlags;
46
47     private FileIconKey(final VirtualFile file, final Project project, final int flags) {
48       myFile = file;
49       myProject = project;
50       myFlags = flags;
51     }
52
53     @Override
54     public boolean equals(final Object o) {
55       if (this == o) return true;
56       if (!(o instanceof FileIconKey)) return false;
57
58       final FileIconKey that = (FileIconKey)o;
59
60       if (myFlags != that.myFlags) return false;
61       if (!myFile.equals(that.myFile)) return false;
62       if (myProject != null ? !myProject.equals(that.myProject) : that.myProject != null) return false;
63
64       return true;
65     }
66
67     @Override
68     public int hashCode() {
69       int result = myFile.hashCode();
70       result = 31 * result + (myProject != null ? myProject.hashCode() : 0);
71       result = 31 * result + myFlags;
72       return result;
73     }
74
75     public VirtualFile getFile() {
76       return myFile;
77     }
78
79     public Project getProject() {
80       return myProject;
81     }
82
83     public int getFlags() {
84       return myFlags;
85     }
86   }
87
88   public static Icon getIcon(final VirtualFile file, final int flags, final Project project) {
89     Icon lastIcon = file.getUserData(Iconable.LAST_COMPUTED_ICON);
90
91     return IconDeferrer.getInstance().defer(lastIcon != null ? lastIcon : file.getIcon(), new FileIconKey(file, project, flags), new Function<FileIconKey, Icon>() {
92       public Icon fun(final FileIconKey key) {
93         VirtualFile file = key.getFile();
94         int flags = key.getFlags();
95         Project project = key.getProject();
96
97         if (!file.isValid() || project != null && project.isDisposed()) return null;
98
99         Icon providersIcon = getProvidersIcon(file, flags, project);
100         Icon icon = providersIcon == null ? file.getIcon() : providersIcon;
101
102         final boolean dumb = project != null && DumbService.getInstance(project).isDumb();
103         for (FileIconPatcher patcher : getPatchers()) {
104           if (dumb && !(patcher instanceof DumbAware)) {
105             continue;
106           }
107
108           icon = patcher.patchIcon(icon, file, flags, project);
109         }
110
111         if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && !file.isWritable()) {
112           icon = new LayeredIcon(icon, Icons.LOCKED_ICON);
113         }
114         
115         file.putUserData(Iconable.LAST_COMPUTED_ICON, icon);
116
117         return icon;
118       }
119     });
120   }
121
122   @Nullable
123   private static Icon getProvidersIcon(VirtualFile file, int flags, Project project) {
124     for (FileIconProvider provider : getProviders()) {
125       final Icon icon = provider.getIcon(file, flags, project);
126       if (icon != null) return icon;
127     }
128     return null;
129   }
130
131   public static Icon getEmptyIcon(boolean showVisibility) {
132     RowIcon baseIcon = new RowIcon(2);
133     baseIcon.setIcon(createEmptyIconLike(Icons.CLASS_ICON_PATH), 0);
134     if (showVisibility) {
135       baseIcon.setIcon(createEmptyIconLike(Icons.PUBLIC_ICON_PATH), 1);
136     }
137     return baseIcon;
138   }
139
140   @Nullable
141   private static Icon createEmptyIconLike(final String baseIconPath) {
142     Icon baseIcon = IconLoader.findIcon(baseIconPath);
143     if (baseIcon == null) {
144       return new EmptyIcon(16, 16);
145     }
146     return new EmptyIcon(baseIcon.getIconWidth(), baseIcon.getIconHeight());
147   }
148
149   private static class FileIconProviderHolder {
150     private static final FileIconProvider[] ourProviders = Extensions.getExtensions(FileIconProvider.EP_NAME);
151   }
152
153   private static FileIconProvider[] getProviders() {
154     return FileIconProviderHolder.ourProviders;
155   }
156
157   private static class FileIconPatcherHolder {
158     private static final FileIconPatcher[] ourPatchers = Extensions.getExtensions(FileIconPatcher.EP_NAME);
159   }
160
161   private static FileIconPatcher[] getPatchers() {
162     return FileIconPatcherHolder.ourPatchers;
163   }
164 }