/* * Copyright 2000-2014 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.ide.actions; import com.intellij.ide.util.PsiElementListCellRenderer; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.presentation.java.SymbolPresentationUtil; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.JBColor; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.ui.FilePathSplittingPolicy; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; import java.util.LinkedList; /** * @author Konstantin Bulenkov */ class SearchEverywherePsiRenderer extends PsiElementListCellRenderer<PsiElement> { private final JList myList; public SearchEverywherePsiRenderer(JList list) { myList = list; } @Override public String getElementText(PsiElement element) { return element instanceof PsiNamedElement ? ((PsiNamedElement)element).getName() : ""; } @Override protected String getContainerText(PsiElement element, String name) { if (element instanceof PsiFileSystemItem) { PsiFileSystemItem parent = ((PsiFileSystemItem)element).getParent(); final PsiDirectory psiDirectory = parent instanceof PsiDirectory ? (PsiDirectory)parent : null; VirtualFile virtualFile = psiDirectory == null ? null : psiDirectory.getVirtualFile(); if (virtualFile == null) return null; final String relativePath = getRelativePath(virtualFile, element.getProject()); if (relativePath == null) return "( " + File.separator + " )"; int width = myList.getWidth(); if (width == 0) width += 800; String path = FilePathSplittingPolicy.SPLIT_BY_SEPARATOR.getOptimalTextForComponent(name, new File(relativePath), this, width - myRightComponentWidth - 16 - 10); return "(" + path + ")"; } return getSymbolContainerText(name, element); } private String getSymbolContainerText(String name, PsiElement element) { String text = SymbolPresentationUtil.getSymbolContainerText(element); if (myList.getWidth() == 0) return text; if (text == null) return null; if (text.startsWith("(") && text.endsWith(")")) { text = text.substring(1, text.length()-1); } boolean in = text.startsWith("in "); if (in) text = text.substring(3); final FontMetrics fm = myList.getFontMetrics(myList.getFont()); final int maxWidth = myList.getWidth() - fm.stringWidth(name) - 16 - myRightComponentWidth - 20; String left = "(" + (in ? "in " : " "); String right = ")"; if (fm.stringWidth(left + text + right) < maxWidth) return left + text + right; final LinkedList<String> parts = new LinkedList<String>(StringUtil.split(text, ".")); int index; while (parts.size() > 1) { index = parts.size() / 2 - 1; parts.remove(index); if (fm.stringWidth(StringUtil.join(parts, ".") + "...") < maxWidth) { parts.add(index, index == 0 ? "..." : "."); return left + StringUtil.join(parts, ".") + right; } } //todo return left + "..." + right; } @Nullable String getRelativePath(final VirtualFile virtualFile, final Project project) { String url = virtualFile.getPresentableUrl(); if (project == null) { return url; } VirtualFile root = ProjectFileIndex.SERVICE.getInstance(project).getContentRootForFile(virtualFile); if (root != null) { return root.getName() + File.separatorChar + VfsUtilCore.getRelativePath(virtualFile, root, File.separatorChar); } final VirtualFile baseDir = project.getBaseDir(); if (baseDir != null) { //noinspection ConstantConditions final String projectHomeUrl = baseDir.getPresentableUrl(); if (url.startsWith(projectHomeUrl)) { final String cont = url.substring(projectHomeUrl.length()); if (cont.isEmpty()) return null; url = "..." + cont; } } return url; } @Override protected boolean customizeNonPsiElementLeftRenderer(ColoredListCellRenderer renderer, JList list, Object value, int index, boolean selected, boolean hasFocus) { if (!(value instanceof NavigationItem)) return false; NavigationItem item = (NavigationItem)value; TextAttributes attributes = getNavigationItemAttributes(item); SimpleTextAttributes nameAttributes = attributes != null ? SimpleTextAttributes.fromTextAttributes(attributes) : null; Color color = list.getForeground(); if (nameAttributes == null) nameAttributes = new SimpleTextAttributes(Font.PLAIN, color); renderer.append(item + " ", nameAttributes); ItemPresentation itemPresentation = item.getPresentation(); assert itemPresentation != null; renderer.setIcon(itemPresentation.getIcon(true)); String locationString = itemPresentation.getLocationString(); if (!StringUtil.isEmpty(locationString)) { renderer.append(locationString, new SimpleTextAttributes(Font.PLAIN, JBColor.GRAY)); } return true; } @Override protected int getIconFlags() { return Iconable.ICON_FLAG_READ_STATUS; } }