/*
* Copyright 2000-2007 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.util;
import com.intellij.ide.IconProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.RowIcon;
import com.intellij.util.ui.EmptyIcon;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class IconUtil {
private static IconProvider[] ourIconProviders = null;
public static Icon getIcon(VirtualFile file, int flags, Project project) {
Icon icon = getBaseIcon(file, flags, project);
Icon excludedIcon = null;
if (project != null) {
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
if (projectFileIndex.isInSource(file) && CompilerManager.getInstance(project).isExcludedFromCompilation(file)) {
excludedIcon = Icons.EXCLUDED_FROM_COMPILE_ICON;
}
}
Icon lockedIcon = null;
if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && !file.isWritable()) {
lockedIcon = Icons.LOCKED_ICON;
}
if (excludedIcon != null || lockedIcon != null) {
LayeredIcon layeredIcon = new LayeredIcon(1 + (lockedIcon != null ? 1 : 0) + (excludedIcon != null ? 1 : 0));
int layer = 0;
layeredIcon.setIcon(icon, layer++);
if (lockedIcon != null) {
layeredIcon.setIcon(lockedIcon, layer++);
}
if (excludedIcon != null) {
layeredIcon.setIcon(excludedIcon, layer);
}
icon = layeredIcon;
}
return icon;
}
private static Icon getBaseIcon(final VirtualFile file, final int flags, final Project project) {
Icon providersIcon = getProvidersIcon(file, flags, project);
Icon icon = providersIcon == null ? file.getIcon() : providersIcon;
if (project != null) {
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final boolean isUnderSource = projectFileIndex.isJavaSourceFile(file);
FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file);
if (fileType == StdFileTypes.JAVA) {
if (!isUnderSource) {
icon = Icons.JAVA_OUTSIDE_SOURCE_ICON;
}
else {
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile instanceof PsiClassOwner) {
PsiClass[] classes = ((PsiClassOwner)psiFile).getClasses();
if (classes.length > 0) {
// prefer icon of the class named after file
final String fileName = file.getNameWithoutExtension();
Icon classIcon = null;
for (PsiClass aClass : classes) {
if (Comparing.strEqual(aClass.getName(), fileName)) {
classIcon = aClass.getIcon(flags);
break;
}
}
if (classIcon == null) classIcon = classes[classes.length - 1].getIcon(flags);
icon = classIcon;
}
}
}
}
}
return icon;
}
@Nullable
private static Icon getProvidersIcon(VirtualFile file, int flags, Project project) {
if(project == null) return null;
final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
return psiFile == null ? null : getProvidersIcon(psiFile, flags);
}
@Nullable
public static Icon getProvidersIcon(PsiElement element, int flags) {
for (final IconProvider iconProvider : getIconProviders()) {
final Icon icon = iconProvider.getIcon(element, flags);
if (icon != null) return icon;
}
return null;
}
private static IconProvider[] getIconProviders() {
if (ourIconProviders == null) {
ourIconProviders = ApplicationManager.getApplication().getComponents(IconProvider.class);
}
return ourIconProviders;
}
public static Icon getEmptyIcon(boolean showVisibility) {
RowIcon baseIcon = new RowIcon(2);
Icon emptyIcon = Icons.CLASS_ICON != null
? new EmptyIcon(Icons.CLASS_ICON.getIconWidth(), Icons.CLASS_ICON.getIconHeight())
: null;
baseIcon.setIcon(emptyIcon, 0);
if (showVisibility) {
emptyIcon = Icons.PUBLIC_ICON != null ? new EmptyIcon(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight()) : null;
baseIcon.setIcon(emptyIcon, 1);
}
return baseIcon;
}
public static void setVisibilityIcon(PsiModifierList modifierList, RowIcon baseIcon) {
if (modifierList != null) {
if (modifierList.hasModifierProperty(PsiModifier.PUBLIC)) {
setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PUBLIC, baseIcon);
}
else if (modifierList.hasModifierProperty(PsiModifier.PRIVATE)) {
setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PRIVATE, baseIcon);
}
else if (modifierList.hasModifierProperty(PsiModifier.PROTECTED)) {
setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PROTECTED, baseIcon);
}
else if (modifierList.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
setVisibilityIcon(PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL, baseIcon);
}
else {
Icon emptyIcon = new EmptyIcon(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight());
baseIcon.setIcon(emptyIcon, 1);
}
}
else if (Icons.PUBLIC_ICON != null) {
Icon emptyIcon = new EmptyIcon(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight());
baseIcon.setIcon(emptyIcon, 1);
}
}
private static void setVisibilityIcon(int accessLevel, RowIcon baseIcon) {
Icon icon;
switch (accessLevel) {
case PsiUtil.ACCESS_LEVEL_PUBLIC:
icon = Icons.PUBLIC_ICON;
break;
case PsiUtil.ACCESS_LEVEL_PROTECTED:
icon = Icons.PROTECTED_ICON;
break;
case PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL:
icon = Icons.PACKAGE_LOCAL_ICON;
break;
case PsiUtil.ACCESS_LEVEL_PRIVATE:
icon = Icons.PRIVATE_ICON;
break;
default:
if (Icons.PUBLIC_ICON != null) {
icon = new EmptyIcon(Icons.PUBLIC_ICON.getIconWidth(), Icons.PUBLIC_ICON.getIconHeight());
}
else {
return;
}
}
baseIcon.setIcon(icon, 1);
}
}