blob: 16aa930b806a81fab77646e84cbdf05abfe88a2b [file] [log] [blame]
/*
* 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.ide.IconProvider;
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.extensions.Extensions;
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.SourceFolder;
import com.intellij.openapi.roots.libraries.LibraryUtil;
import com.intellij.openapi.roots.ui.configuration.ModuleSourceRootEditHandler;
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.util.registry.Registry;
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.projectImport.ProjectAttachProcessor;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.impl.file.PsiDirectoryFactory;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.RowIcon;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.IconUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.PlatformUtils;
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);
}
protected boolean shouldShowModuleName() {
return !PlatformUtils.isCidr();
}
@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 (!shouldShowModuleName()) {
data.addText(directoryFile.getName() + " ", SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
else 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 {
SourceFolder sourceRoot = ProjectRootsUtil.getModuleSourceRoot(directoryFile, project);
if (sourceRoot != null) {
String rootTypeName = ModuleSourceRootEditHandler.getEditHandler(sourceRoot.getRootType()).getRootTypeName();
data.addText(" (" + rootTypeName.toLowerCase() + " root)", SimpleTextAttributes.GRAY_ATTRIBUTES);
}
}
setupIcon(data, psiDirectory);
return;
}
}
final String name = parentValue instanceof Project
? psiDirectory.getVirtualFile().getPresentableUrl()
: ProjectViewDirectoryHelper.getInstance(psiDirectory.getProject()).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(ProjectViewDirectoryHelper.getInstance(project).getLocationString(psiDirectory));
}
setupIcon(data, psiDirectory);
}
protected void setupIcon(PresentationData data, PsiDirectory psiDirectory) {
final VirtualFile virtualFile = psiDirectory.getVirtualFile();
if (PlatformUtils.isAppCode()) {
final Icon icon = IconUtil.getIcon(virtualFile, 0, myProject);
if (icon != null) {
data.setIcon(patchIcon(icon, virtualFile));
}
}
else {
for (final IconProvider provider : Extensions.getExtensions(IconProvider.EXTENSION_POINT_NAME)) {
final Icon icon = provider.getIcon(psiDirectory, 0);
if (icon != null) {
data.setIcon(patchIcon(icon, virtualFile));
return;
}
}
}
}
@Override
public Collection<AbstractTreeNode> getChildrenImpl() {
return ProjectViewDirectoryHelper.getInstance(myProject).getDirectoryChildren(getValue(), getSettings(), true);
}
@Override
@SuppressWarnings("deprecation")
public String getTestPresentation() {
return "PsiDirectory: " + getValue().getName();
}
public boolean isFQNameShown() {
return ProjectViewDirectoryHelper.getInstance(getProject()).isShowFQName(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;
}
if (Registry.is("ide.hide.excluded.files")) {
final Project project = value.getProject();
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
return !fileIndex.isExcluded(file);
}
else {
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 ProjectViewDirectoryHelper.getInstance(getProject()).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.isModuleSourceRoot(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 && project != null) {
if (ProjectRootsUtil.isModuleContentRoot(file, project) || ProjectRootsUtil.isModuleSourceRoot(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 PsiDirectoryFactory.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, PlatformIcons.LOCKED_ICON);
}
if (file.is(VFileProperty.SYMLINK)) {
icon = LayeredIcon.create(icon, PlatformIcons.SYMLINK_ICON);
}
return icon;
}
@Override
public Comparable getSortKey() {
if (ProjectAttachProcessor.canAttachToProject()) {
// primary module is always on top; attached modules are sorted alphabetically
final VirtualFile file = getVirtualFile();
if (Comparing.equal(file, myProject.getBaseDir())) {
return ""; // sorts before any other name
}
return getTitle();
}
return null;
}
@Override
public String getQualifiedNameSortKey() {
final PsiDirectoryFactory factory = PsiDirectoryFactory.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;
}
}