- use editor font in implements/override popup
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / util / gotoByName / GotoFileCellRenderer.java
1 /*
2  * Copyright 2000-2015 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
17 package com.intellij.ide.util.gotoByName;
18
19 import com.intellij.ide.util.PlatformModuleRendererFactory;
20 import com.intellij.ide.util.PsiElementListCellRenderer;
21 import com.intellij.navigation.ItemPresentation;
22 import com.intellij.navigation.NavigationItem;
23 import com.intellij.openapi.editor.markup.TextAttributes;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.roots.ProjectFileIndex;
26 import com.intellij.openapi.util.Iconable;
27 import com.intellij.openapi.util.text.StringUtil;
28 import com.intellij.openapi.vfs.VfsUtilCore;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.psi.PsiDirectory;
31 import com.intellij.psi.PsiFileSystemItem;
32 import com.intellij.ui.ColoredListCellRenderer;
33 import com.intellij.ui.JBColor;
34 import com.intellij.ui.SimpleTextAttributes;
35 import com.intellij.util.ui.FilePathSplittingPolicy;
36 import org.jetbrains.annotations.Nullable;
37
38 import javax.swing.*;
39 import java.awt.*;
40 import java.io.File;
41
42 public class GotoFileCellRenderer extends PsiElementListCellRenderer<PsiFileSystemItem> {
43   private final int myMaxWidth;
44
45   public GotoFileCellRenderer(int maxSize) {
46     myMaxWidth = maxSize;
47   }
48
49   @Override
50   public String getElementText(PsiFileSystemItem element) {
51     return element.getName();
52   }
53
54   @Override
55   public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
56     if (value == ChooseByNameBase.NON_PREFIX_SEPARATOR) {
57       Object previousElement = index > 0 ? list.getModel().getElementAt(index - 1) : null;
58       return ChooseByNameBase.renderNonPrefixSeparatorComponent(getBackgroundColor(previousElement));
59     }
60     else {
61       return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
62     }
63   }
64
65   @Override
66   protected String getContainerText(PsiFileSystemItem element, String name) {
67     PsiFileSystemItem parent = element.getParent();
68     final PsiDirectory psiDirectory = parent instanceof PsiDirectory ? (PsiDirectory)parent : null;
69     if (psiDirectory == null) return null;
70     final VirtualFile virtualFile = psiDirectory.getVirtualFile();
71     final String relativePath = getRelativePath(virtualFile, element.getProject());
72     if (relativePath == null) return "( " + File.separator + " )";
73     String path =
74       FilePathSplittingPolicy.SPLIT_BY_SEPARATOR.getOptimalTextForComponent(name + "          ", new File(relativePath), this, myMaxWidth);
75     return "(" + path + ")";
76   }
77
78   @Nullable
79   static String getRelativePath(final VirtualFile virtualFile, final Project project) {
80     String url = virtualFile.getPresentableUrl();
81     if (project == null) {
82       return url;
83     }
84     VirtualFile root = ProjectFileIndex.SERVICE.getInstance(project).getContentRootForFile(virtualFile);
85     if (root != null) {
86       return root.getName() + File.separatorChar + VfsUtilCore.getRelativePath(virtualFile, root, File.separatorChar);
87     }
88
89     final VirtualFile baseDir = project.getBaseDir();
90     if (baseDir != null) {
91       //noinspection ConstantConditions
92       final String projectHomeUrl = baseDir.getPresentableUrl();
93       if (url.startsWith(projectHomeUrl)) {
94         final String cont = url.substring(projectHomeUrl.length());
95         if (cont.isEmpty()) return null;
96         url = "..." + cont;
97       }
98     }
99     return url;
100   }
101
102   @Override
103   protected boolean customizeNonPsiElementLeftRenderer(ColoredListCellRenderer renderer,
104                                                        JList list,
105                                                        Object value,
106                                                        int index,
107                                                        boolean selected,
108                                                        boolean hasFocus) {
109     if (!(value instanceof NavigationItem)) return false;
110
111     NavigationItem item = (NavigationItem)value;
112
113     TextAttributes attributes = getNavigationItemAttributes(item);
114
115     SimpleTextAttributes nameAttributes = attributes != null ? SimpleTextAttributes.fromTextAttributes(attributes) : null;
116
117     Color color = list.getForeground();
118     if (nameAttributes == null) nameAttributes = new SimpleTextAttributes(Font.PLAIN, color);
119
120     renderer.append(item + " ", nameAttributes);
121     ItemPresentation itemPresentation = item.getPresentation();
122     assert itemPresentation != null;
123     renderer.setIcon(itemPresentation.getIcon(true));
124
125     String locationString = itemPresentation.getLocationString();
126     if (!StringUtil.isEmpty(locationString)) {
127       renderer.append(locationString, new SimpleTextAttributes(Font.PLAIN, JBColor.GRAY));
128     }
129     return true;
130   }
131
132   @Override
133   protected DefaultListCellRenderer getRightCellRenderer(final Object value) {
134     final DefaultListCellRenderer rightRenderer = super.getRightCellRenderer(value);
135     if (rightRenderer instanceof PlatformModuleRendererFactory.PlatformModuleRenderer) {
136       // that renderer will display file path, but we're showing it ourselves - no need to show twice
137       return null;
138     }
139     return rightRenderer;
140   }
141
142   @Override
143   protected int getIconFlags() {
144     return Iconable.ICON_FLAG_READ_STATUS;
145   }
146 }