/* * 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.usages.impl.rules; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataSink; import com.intellij.openapi.actionSystem.TypeSafeDataProvider; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiManager; import com.intellij.usages.Usage; import com.intellij.usages.UsageGroup; import com.intellij.usages.UsageTarget; import com.intellij.usages.UsageView; import com.intellij.usages.rules.SingleParentUsageGroupingRule; import com.intellij.usages.rules.UsageInFile; import com.intellij.util.IconUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.File; /** * @author yole */ public class DirectoryGroupingRule extends SingleParentUsageGroupingRule implements DumbAware { public static DirectoryGroupingRule getInstance(Project project) { return ServiceManager.getService(project, DirectoryGroupingRule.class); } protected final Project myProject; public DirectoryGroupingRule(Project project) { myProject = project; } @Nullable @Override protected UsageGroup getParentGroupFor(@NotNull Usage usage, @NotNull UsageTarget[] targets) { if (usage instanceof UsageInFile) { UsageInFile usageInFile = (UsageInFile)usage; VirtualFile file = usageInFile.getFile(); if (file != null) { if (file instanceof VirtualFileWindow) { file = ((VirtualFileWindow)file).getDelegate(); } VirtualFile dir = file.getParent(); if (dir == null) return null; return getGroupForFile(dir); } } return null; } protected UsageGroup getGroupForFile(@NotNull VirtualFile dir) { return new DirectoryGroup(dir); } public String getActionTitle() { return "Group by directory"; } private class DirectoryGroup implements UsageGroup, TypeSafeDataProvider { private final VirtualFile myDir; private Icon myIcon; private DirectoryGroup(@NotNull VirtualFile dir) { myDir = dir; update(); } @Override public void update() { if (isValid()) { myIcon = IconUtil.getIcon(myDir, 0, myProject); } } @Override public Icon getIcon(boolean isOpen) { return myIcon; } @Override @NotNull public String getText(UsageView view) { VirtualFile baseDir = myProject.getBaseDir(); String relativePath = baseDir == null ? null : VfsUtilCore.getRelativePath(myDir, baseDir, File.separatorChar); return relativePath == null ? myDir.getPresentableUrl() : relativePath; } @Override public FileStatus getFileStatus() { return isValid() ? FileStatusManager.getInstance(myProject).getStatus(myDir) : null; } @Override public boolean isValid() { return myDir.isValid(); } @Override public void navigate(boolean focus) throws UnsupportedOperationException { final PsiDirectory directory = getDirectory(); if (directory != null && directory.canNavigate()) { directory.navigate(focus); } } private PsiDirectory getDirectory() { return myDir.isValid() ? PsiManager.getInstance(myProject).findDirectory(myDir) : null; } @Override public boolean canNavigate() { final PsiDirectory directory = getDirectory(); return directory != null && directory.canNavigate(); } @Override public boolean canNavigateToSource() { return false; } @Override public int compareTo(@NotNull UsageGroup usageGroup) { return getText(null).compareToIgnoreCase(usageGroup.getText(null)); } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof DirectoryGroup)) return false; return myDir.equals(((DirectoryGroup)o).myDir); } public int hashCode() { return myDir.hashCode(); } @Override public void calcData(final DataKey key, final DataSink sink) { if (!isValid()) return; if (CommonDataKeys.VIRTUAL_FILE == key) { sink.put(CommonDataKeys.VIRTUAL_FILE, myDir); } if (CommonDataKeys.PSI_ELEMENT == key) { sink.put(CommonDataKeys.PSI_ELEMENT, getDirectory()); } } @Override public String toString() { return "Directory:" + myDir.getName(); } } }