2 * Copyright 2000-2012 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.openapi.roots.ui;
18 import com.intellij.openapi.module.Module;
19 import com.intellij.openapi.module.ModuleType;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.project.ProjectBundle;
22 import com.intellij.openapi.projectRoots.Sdk;
23 import com.intellij.openapi.projectRoots.SdkType;
24 import com.intellij.openapi.roots.*;
25 import com.intellij.openapi.roots.impl.libraries.LibraryEx;
26 import com.intellij.openapi.roots.libraries.Library;
27 import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
28 import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager;
29 import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
30 import com.intellij.openapi.roots.ui.util.CompositeAppearance;
31 import com.intellij.openapi.roots.ui.util.SimpleTextCellAppearance;
32 import com.intellij.openapi.util.IconLoader;
33 import com.intellij.openapi.util.SystemInfo;
34 import com.intellij.openapi.util.text.StringUtil;
35 import com.intellij.openapi.vfs.JarFileSystem;
36 import com.intellij.openapi.vfs.VfsUtilCore;
37 import com.intellij.openapi.vfs.VirtualFile;
38 import com.intellij.openapi.vfs.VirtualFileManager;
39 import com.intellij.openapi.vfs.impl.LightFilePointer;
40 import com.intellij.ui.JBColor;
41 import com.intellij.ui.SimpleTextAttributes;
42 import com.intellij.util.PathUtil;
43 import com.intellij.util.PlatformIcons;
44 import org.jetbrains.annotations.NotNull;
45 import org.jetbrains.annotations.Nullable;
51 public class OrderEntryAppearanceServiceImpl extends OrderEntryAppearanceService {
52 private static final Icon EXCLUDE_FOLDER_ICON = IconLoader.getDisabledIcon(PlatformIcons.FOLDER_ICON);
54 private static final String NO_JDK = ProjectBundle.message("jdk.missing.item");
58 public CellAppearanceEx forOrderEntry(Project project, @NotNull final OrderEntry orderEntry, final boolean selected) {
59 if (orderEntry instanceof JdkOrderEntry) {
60 JdkOrderEntry jdkLibraryEntry = (JdkOrderEntry)orderEntry;
61 Sdk jdk = jdkLibraryEntry.getJdk();
62 if (!orderEntry.isValid()) {
63 final String oldJdkName = jdkLibraryEntry.getJdkName();
64 return FileAppearanceService.getInstance().forInvalidUrl(oldJdkName != null ? oldJdkName : NO_JDK);
66 return forJdk(jdk, false, selected, true);
68 else if (!orderEntry.isValid()) {
69 return FileAppearanceService.getInstance().forInvalidUrl(orderEntry.getPresentableName());
71 else if (orderEntry instanceof LibraryOrderEntry) {
72 LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry;
73 if (!libraryOrderEntry.isValid()) { //library can be removed
74 return FileAppearanceService.getInstance().forInvalidUrl(orderEntry.getPresentableName());
76 Library library = libraryOrderEntry.getLibrary();
77 assert library != null : libraryOrderEntry;
78 return forLibrary(project, library, !((LibraryEx)library).getInvalidRootUrls(OrderRootType.CLASSES).isEmpty());
80 else if (orderEntry.isSynthetic()) {
81 String presentableName = orderEntry.getPresentableName();
82 Icon icon = orderEntry instanceof ModuleSourceOrderEntry ? sourceFolderIcon(false) : null;
83 return new SimpleTextCellAppearance(presentableName, icon, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES);
85 else if (orderEntry instanceof ModuleOrderEntry) {
86 final Icon icon = ModuleType.get(((ModuleOrderEntry)orderEntry).getModule()).getIcon();
87 return SimpleTextCellAppearance.regular(orderEntry.getPresentableName(), icon);
90 return CompositeAppearance.single(orderEntry.getPresentableName());
96 public CellAppearanceEx forLibrary(Project project, @NotNull final Library library, final boolean hasInvalidRoots) {
97 final StructureConfigurableContext context = ProjectStructureConfigurable.getInstance(project).getContext();
98 final Icon icon = LibraryPresentationManager.getInstance().getCustomIcon(library, context);
100 final String name = library.getName();
102 return normalOrRedWaved(name, (icon != null ? icon : PlatformIcons.LIBRARY_ICON), hasInvalidRoots);
105 final String[] files = library.getUrls(OrderRootType.CLASSES);
106 if (files.length == 0) {
107 return SimpleTextCellAppearance.invalid(ProjectBundle.message("library.empty.library.item"), PlatformIcons.LIBRARY_ICON);
109 else if (files.length == 1) {
110 return forVirtualFilePointer(new LightFilePointer(files[0]));
113 final String url = StringUtil.trimEnd(files[0], JarFileSystem.JAR_SEPARATOR);
114 String text = ProjectBundle.message("library.unnamed.text", PathUtil.getFileName(url), files.length - 1);
115 return SimpleTextCellAppearance.regular(text, PlatformIcons.LIBRARY_ICON);
120 public CellAppearanceEx forJdk(@Nullable final Sdk jdk, final boolean isInComboBox, final boolean selected, final boolean showVersion) {
122 return FileAppearanceService.getInstance().forInvalidUrl(NO_JDK);
125 String name = jdk.getName();
126 CompositeAppearance appearance = new CompositeAppearance();
127 SdkType sdkType = (SdkType)jdk.getSdkType();
128 appearance.setIcon(sdkType.getIcon());
129 SimpleTextAttributes attributes = getTextAttributes(sdkType.sdkHasValidPath(jdk), selected);
130 CompositeAppearance.DequeEnd ending = appearance.getEnding();
131 ending.addText(name, attributes);
134 String versionString = jdk.getVersionString();
135 if (versionString != null && !versionString.equals(name)) {
136 SimpleTextAttributes textAttributes = isInComboBox && !selected ? SimpleTextAttributes.SYNTHETIC_ATTRIBUTES :
137 SystemInfo.isMac && selected ? new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN,
138 Color.WHITE): SimpleTextAttributes.GRAY_ATTRIBUTES;
139 ending.addComment(versionString, textAttributes);
143 return ending.getAppearance();
146 private static SimpleTextAttributes getTextAttributes(final boolean valid, final boolean selected) {
148 return SimpleTextAttributes.ERROR_ATTRIBUTES;
150 else if (selected && !(SystemInfo.isWinVistaOrNewer && UIManager.getLookAndFeel().getName().contains("Windows"))) {
151 return SimpleTextAttributes.SELECTED_SIMPLE_CELL_ATTRIBUTES;
154 return SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES;
160 public CellAppearanceEx forContentFolder(@NotNull final ContentFolder folder) {
161 if (folder instanceof SourceFolder) {
162 return formatRelativePath(folder, PlatformIcons.FOLDER_ICON);
164 else if (folder instanceof ExcludeFolder) {
165 return formatRelativePath(folder, EXCLUDE_FOLDER_ICON);
168 throw new RuntimeException(folder.getClass().getName());
174 public CellAppearanceEx forModule(@NotNull final Module module) {
175 return SimpleTextCellAppearance.regular(module.getName(), ModuleType.get(module).getIcon());
179 private static Icon sourceFolderIcon(final boolean testSource) {
180 return testSource ? PlatformIcons.TEST_SOURCE_FOLDER : PlatformIcons.SOURCE_FOLDERS_ICON;
184 private static CellAppearanceEx normalOrRedWaved(@NotNull final String text, @Nullable final Icon icon, final boolean waved) {
185 return waved ? new SimpleTextCellAppearance(text, icon, new SimpleTextAttributes(SimpleTextAttributes.STYLE_WAVED, null, JBColor.RED))
186 : SimpleTextCellAppearance.regular(text, icon);
190 private static CellAppearanceEx forVirtualFilePointer(@NotNull final LightFilePointer filePointer) {
191 final VirtualFile file = filePointer.getFile();
192 return file != null ? FileAppearanceService.getInstance().forVirtualFile(file)
193 : FileAppearanceService.getInstance().forInvalidUrl(filePointer.getPresentableUrl());
197 private static CellAppearanceEx formatRelativePath(@NotNull final ContentFolder folder, @NotNull final Icon icon) {
198 LightFilePointer folderFile = new LightFilePointer(folder.getUrl());
199 VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(folder.getContentEntry().getUrl());
200 if (file == null) return FileAppearanceService.getInstance().forInvalidUrl(folderFile.getPresentableUrl());
202 String contentPath = file.getPath();
204 SimpleTextAttributes textAttributes;
205 VirtualFile folderFileFile = folderFile.getFile();
206 if (folderFileFile == null) {
207 String absolutePath = folderFile.getPresentableUrl();
208 relativePath = absolutePath.startsWith(contentPath) ? absolutePath.substring(contentPath.length()) : absolutePath;
209 textAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
212 relativePath = VfsUtilCore.getRelativePath(folderFileFile, file, File.separatorChar);
213 textAttributes = SimpleTextAttributes.REGULAR_ATTRIBUTES;
216 relativePath = StringUtil.isEmpty(relativePath) ? "." + File.separatorChar : relativePath;
217 return new SimpleTextCellAppearance(relativePath, icon, textAttributes);