/* * Copyright 2000-2013 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.projectView.impl.nodes; import com.intellij.icons.AllIcons; import com.intellij.ide.bookmarks.Bookmark; import com.intellij.ide.bookmarks.BookmarkManager; import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.projectView.ProjectView; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.ProjectRootsUtil; import com.intellij.ide.projectView.impl.ProjectViewImpl; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VFileProperty; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.NavigatableWithText; import com.intellij.psi.PsiDirectory; import com.intellij.psi.impl.file.PsiPackageHelper; import com.intellij.ui.LayeredIcon; import com.intellij.ui.RowIcon; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.PathUtil; import consulo.fileTypes.impl.VfsIconUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.Collection; public class PsiDirectoryNode extends BasePsiNode<PsiDirectory> implements NavigatableWithText { public PsiDirectoryNode(Project project, PsiDirectory value, ViewSettings viewSettings) { super(project, value, viewSettings); } @Override protected void updateImpl(PresentationData data) { final Project project = getProject(); final PsiDirectory psiDirectory = getValue(); final VirtualFile directoryFile = psiDirectory.getVirtualFile(); final Object parentValue = getParentValue(); if (ProjectRootsUtil.isModuleContentRoot(directoryFile, project)) { ProjectFileIndex fi = ProjectRootManager.getInstance(project).getFileIndex(); Module module = fi.getModuleForFile(directoryFile); data.setPresentableText(directoryFile.getName()); if (module != null) { if (!(parentValue instanceof Module)) { if (Comparing.equal(module.getName(), directoryFile.getName())) { data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); } else { data.addText(directoryFile.getName() + " ", SimpleTextAttributes.REGULAR_ATTRIBUTES); data.addText("[" + module.getName() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); } } else { data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); } if (parentValue instanceof Module || parentValue instanceof Project) { final String location = FileUtil.getLocationRelativeToUserHome(directoryFile.getPresentableUrl()); data.addText(" (" + location + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); } else if (ProjectRootsUtil.isSourceOrTestRoot(directoryFile, project)) { if (ProjectRootsUtil.isInTestSource(directoryFile, project)) { data.addText(" (test source root)", SimpleTextAttributes.GRAY_ATTRIBUTES); } else { data.addText(" (source root)", SimpleTextAttributes.GRAY_ATTRIBUTES); } } setupIcon(data, psiDirectory); return; } } final String name = parentValue instanceof Project ? psiDirectory.getVirtualFile().getPresentableUrl() : BaseProjectViewDirectoryHelper.getNodeName(getSettings(), parentValue, psiDirectory); if (name == null) { setValue(null); return; } data.setPresentableText(name); if (ProjectRootsUtil.isLibraryRoot(directoryFile, project)) { data.setLocationString("library home"); } else { data.setLocationString(BaseProjectViewDirectoryHelper.getLocationString(psiDirectory)); } setupIcon(data, psiDirectory); } protected void setupIcon(PresentationData data, PsiDirectory psiDirectory) { final VirtualFile virtualFile = psiDirectory.getVirtualFile(); final Icon icon = VfsIconUtil.getIcon(virtualFile, 0, myProject); data.setIcon(patchIcon(icon, virtualFile)); } @Override public Collection<AbstractTreeNode> getChildrenImpl() { return BaseProjectViewDirectoryHelper.getDirectoryChildren(getValue(), getSettings(), true); } @Override @SuppressWarnings("deprecation") public String getTestPresentation() { return "PsiDirectory: " + getValue().getName(); } public boolean isFQNameShown() { return BaseProjectViewDirectoryHelper.isShowFQName(getProject(), getSettings(), getParentValue(), getValue()); } @Override public boolean contains(@NotNull VirtualFile file) { final PsiDirectory value = getValue(); if (value == null) { return false; } VirtualFile directory = value.getVirtualFile(); if (directory.getFileSystem() instanceof LocalFileSystem) { file = PathUtil.getLocalFile(file); } if (!VfsUtilCore.isAncestor(directory, file, false)) { return false; } return !FileTypeRegistry.getInstance().isFileIgnored(file); } @Override public VirtualFile getVirtualFile() { PsiDirectory directory = getValue(); if (directory == null) return null; return directory.getVirtualFile(); } @Override public boolean canRepresent(final Object element) { if (super.canRepresent(element)) return true; PsiDirectory directory = getValue(); if (directory == null) return false; return BaseProjectViewDirectoryHelper.canRepresent(element, directory); } @Override public boolean canNavigate() { VirtualFile file = getVirtualFile(); Project project = getProject(); ProjectSettingsService service = ProjectSettingsService.getInstance(myProject); return file != null && ((ProjectRootsUtil.isModuleContentRoot(file, project) && service.canOpenModuleSettings()) || (ProjectRootsUtil.isSourceOrTestRoot(file, project) && service.canOpenContentEntriesSettings()) || (ProjectRootsUtil.isLibraryRoot(file, project) && service.canOpenModuleLibrarySettings())); } @Override public boolean canNavigateToSource() { return false; } @Override public void navigate(final boolean requestFocus) { Module module = ModuleUtil.findModuleForPsiElement(getValue()); if (module != null) { final VirtualFile file = getVirtualFile(); final Project project = getProject(); ProjectSettingsService service = ProjectSettingsService.getInstance(myProject); if (ProjectRootsUtil.isModuleContentRoot(file, project)) { service.openModuleSettings(module); } else if (ProjectRootsUtil.isLibraryRoot(file, project)) { final OrderEntry orderEntry = LibraryUtil.findLibraryEntry(file, module.getProject()); if (orderEntry != null) { service.openLibraryOrSdkSettings(orderEntry); } } else { service.openContentEntriesSettings(module); } } } @Override public String getNavigateActionText(boolean focusEditor) { VirtualFile file = getVirtualFile(); Project project = getProject(); if (file != null) { if (ProjectRootsUtil.isModuleContentRoot(file, project) || ProjectRootsUtil.isSourceOrTestRoot(file, project)) { return "Open Module Settings"; } if (ProjectRootsUtil.isLibraryRoot(file, project)) { return "Open Library Settings"; } } return null; } @Override public int getWeight() { final ProjectView projectView = ProjectView.getInstance(myProject); if (projectView instanceof ProjectViewImpl && !((ProjectViewImpl)projectView).isFoldersAlwaysOnTop()) { return 20; } return isFQNameShown() ? 70 : 0; } @Override public String getTitle() { final PsiDirectory directory = getValue(); if (directory != null) { return PsiPackageHelper.getInstance(getProject()).getQualifiedName(directory, true); } return super.getTitle(); } protected Icon patchIcon(Icon original, VirtualFile file) { Icon icon = original; final Bookmark bookmarkAtFile = BookmarkManager.getInstance(myProject).findFileBookmark(file); if (bookmarkAtFile != null) { final RowIcon composite = new RowIcon(2, RowIcon.Alignment.CENTER); composite.setIcon(icon, 0); composite.setIcon(bookmarkAtFile.getIcon(), 1); icon = composite; } if (!file.isWritable()) { icon = LayeredIcon.create(icon, AllIcons.Nodes.Locked); } if (file.is(VFileProperty.SYMLINK)) { icon = LayeredIcon.create(icon, AllIcons.Nodes.Symlink); } return icon; } @Override public String getQualifiedNameSortKey() { final PsiPackageHelper factory = PsiPackageHelper.getInstance(getProject()); return factory.getQualifiedName(getValue(), true); } @Override public int getTypeSortWeight(final boolean sortByType) { return 3; } @Override public boolean shouldDrillDownOnEmptyElement() { return true; } @Override public boolean isAlwaysShowPlus() { final VirtualFile file = getVirtualFile(); return file == null || file.getChildren().length > 0; } }