Merge branch 'dany/grails-project-view'

# Conflicts:
#	platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
This commit is contained in:
Daniil Ovchinnikov
2016-08-23 22:03:45 +03:00
6 changed files with 123 additions and 37 deletions
@@ -19,6 +19,7 @@ import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PackageElement;
import com.intellij.ide.projectView.impl.nodes.PackageUtil;
import com.intellij.ide.projectView.impl.nodes.ProjectViewDirectoryHelper;
import com.intellij.ide.projectView.impl.nodes.PsiFileSystemItemFilter;
import com.intellij.ide.util.treeView.TreeViewUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.impl.DirectoryIndex;
@@ -91,8 +92,11 @@ public class JavaProjectViewDirectoryHelper extends ProjectViewDirectoryHelper {
}
@Override
public boolean isEmptyMiddleDirectory(final PsiDirectory directory, final boolean strictlyEmpty) {
return JavaDirectoryService.getInstance().getPackage(directory) != null && TreeViewUtil.isEmptyMiddlePackage(directory, strictlyEmpty);
public boolean isEmptyMiddleDirectory(final PsiDirectory directory,
final boolean strictlyEmpty,
@Nullable PsiFileSystemItemFilter filter) {
return JavaDirectoryService.getInstance().getPackage(directory) != null &&
TreeViewUtil.isEmptyMiddlePackage(directory, strictlyEmpty, filter);
}
@Override
@@ -15,18 +15,17 @@
*/
package com.intellij.ide.util.treeView;
import com.intellij.ide.projectView.impl.nodes.PsiFileSystemItemFilter;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderEx;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaDirectoryService;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.ConcurrentMap;
@@ -94,8 +93,11 @@ public class TreeViewUtil {
*
* @param strictlyEmpty if true, the package is considered empty if it has only 1 child and this child is a directory
* otherwise the package is considered as empty if all direct children that it has are directories
* @param filter if returns false for some element, that elements is not counted
*/
public static boolean isEmptyMiddlePackage(@NotNull PsiDirectory dir, boolean strictlyEmpty) {
public static boolean isEmptyMiddlePackage(@NotNull PsiDirectory dir,
boolean strictlyEmpty,
@Nullable PsiFileSystemItemFilter filter) {
final VirtualFile[] files = dir.getVirtualFile().getChildren();
if (files.length == 0) {
return false;
@@ -105,9 +107,13 @@ public class TreeViewUtil {
int directoriesCount = 0;
for (VirtualFile file : files) {
if (FileTypeManager.getInstance().isFileIgnored(file)) continue;
if (!file.isDirectory()) return false;
if (!file.isDirectory()) {
if (filter == null) return false;
PsiFile childFile = manager.findFile(file);
if (childFile != null && filter.shouldShow(childFile)) return false;
}
PsiDirectory childDir = manager.findDirectory(file);
if (childDir != null) {
if (childDir != null && (filter == null || filter.shouldShow(childDir))) {
directoriesCount++;
if (strictlyEmpty && directoriesCount > 1) return false;
if (JavaDirectoryService.getInstance().getPackage(childDir) != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -123,6 +123,12 @@ public class ProjectViewDirectoryHelper {
}
public boolean isEmptyMiddleDirectory(PsiDirectory directory, final boolean strictlyEmpty) {
return isEmptyMiddleDirectory(directory, strictlyEmpty, null);
}
public boolean isEmptyMiddleDirectory(PsiDirectory directory,
final boolean strictlyEmpty,
@Nullable PsiFileSystemItemFilter filter) {
return false;
}
@@ -142,9 +148,18 @@ public class ProjectViewDirectoryHelper {
return false;
}
@NotNull
public Collection<AbstractTreeNode> getDirectoryChildren(final PsiDirectory psiDirectory,
final ViewSettings settings,
final boolean withSubDirectories) {
return getDirectoryChildren(psiDirectory, settings, withSubDirectories, null);
}
@NotNull
public Collection<AbstractTreeNode> getDirectoryChildren(final PsiDirectory psiDirectory,
final ViewSettings settings,
final boolean withSubDirectories,
@Nullable PsiFileSystemItemFilter filter) {
final List<AbstractTreeNode> children = new ArrayList<>();
final Project project = psiDirectory.getProject();
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
@@ -152,17 +167,17 @@ public class ProjectViewDirectoryHelper {
final ModuleFileIndex moduleFileIndex = module == null ? null : ModuleRootManager.getInstance(module).getFileIndex();
if (!settings.isFlattenPackages() || skipDirectory(psiDirectory)) {
processPsiDirectoryChildren(psiDirectory, directoryChildrenInProject(psiDirectory, settings),
children, fileIndex, null, settings, withSubDirectories);
children, fileIndex, null, settings, withSubDirectories, filter);
}
else { // source directory in "flatten packages" mode
final PsiDirectory parentDir = psiDirectory.getParentDirectory();
if (parentDir == null || skipDirectory(parentDir) && withSubDirectories) {
addAllSubpackages(children, psiDirectory, moduleFileIndex, settings);
addAllSubpackages(children, psiDirectory, moduleFileIndex, settings, filter);
}
if (withSubDirectories) {
PsiDirectory[] subdirs = psiDirectory.getSubdirectories();
for (PsiDirectory subdir : subdirs) {
if (!skipDirectory(subdir)) {
if (!skipDirectory(subdir) || filter != null && !filter.shouldShow(subdir)) {
continue;
}
VirtualFile directoryFile = subdir.getVirtualFile();
@@ -174,11 +189,11 @@ public class ProjectViewDirectoryHelper {
if (FileTypeRegistry.getInstance().isFileIgnored(directoryFile)) continue;
}
children.add(new PsiDirectoryNode(project, subdir, settings));
children.add(new PsiDirectoryNode(project, subdir, settings, filter));
}
}
processPsiDirectoryChildren(psiDirectory, psiDirectory.getFiles(), children, fileIndex, moduleFileIndex, settings,
withSubDirectories);
withSubDirectories, filter);
}
return children;
}
@@ -260,7 +275,8 @@ public class ProjectViewDirectoryHelper {
ProjectFileIndex projectFileIndex,
@Nullable ModuleFileIndex moduleFileIndex,
ViewSettings viewSettings,
boolean withSubDirectories) {
boolean withSubDirectories,
@Nullable PsiFileSystemItemFilter filter) {
for (PsiElement child : children) {
LOG.assertTrue(child.isValid());
@@ -275,6 +291,9 @@ public class ProjectViewDirectoryHelper {
if (moduleFileIndex != null && !moduleFileIndex.isInContent(vFile)) {
continue;
}
if (filter != null && !filter.shouldShow((PsiFileSystemItem)child)) {
continue;
}
if (child instanceof PsiFile) {
container.add(new PsiFileNode(child.getProject(), (PsiFile) child, viewSettings));
}
@@ -282,13 +301,14 @@ public class ProjectViewDirectoryHelper {
if (withSubDirectories) {
PsiDirectory dir = (PsiDirectory)child;
if (!vFile.equals(projectFileIndex.getSourceRootForFile(vFile))) { // if is not a source root
if (viewSettings.isHideEmptyMiddlePackages() && !skipDirectory(psiDir) && isEmptyMiddleDirectory(dir, true)) {
processPsiDirectoryChildren(dir, directoryChildrenInProject(dir, viewSettings),
container, projectFileIndex, moduleFileIndex, viewSettings, withSubDirectories); // expand it recursively
if (viewSettings.isHideEmptyMiddlePackages() && !skipDirectory(psiDir) && isEmptyMiddleDirectory(dir, true, filter)) {
processPsiDirectoryChildren(
dir, directoryChildrenInProject(dir, viewSettings), container, projectFileIndex, moduleFileIndex, viewSettings, true, filter
); // expand it recursively
continue;
}
}
container.add(new PsiDirectoryNode(child.getProject(), (PsiDirectory) child, viewSettings));
container.add(new PsiDirectoryNode(child.getProject(), (PsiDirectory)child, viewSettings, filter));
}
}
}
@@ -298,27 +318,28 @@ public class ProjectViewDirectoryHelper {
public void addAllSubpackages(List<AbstractTreeNode> container,
PsiDirectory dir,
@Nullable ModuleFileIndex moduleFileIndex,
ViewSettings viewSettings) {
ViewSettings viewSettings,
@Nullable PsiFileSystemItemFilter filter) {
final Project project = dir.getProject();
PsiDirectory[] subdirs = dir.getSubdirectories();
for (PsiDirectory subdir : subdirs) {
if (skipDirectory(subdir)) {
if (skipDirectory(subdir) || filter != null && !filter.shouldShow(subdir)) {
continue;
}
if (moduleFileIndex != null && !moduleFileIndex.isInContent(subdir.getVirtualFile())) {
container.add(new PsiDirectoryNode(project, subdir, viewSettings));
container.add(new PsiDirectoryNode(project, subdir, viewSettings, filter));
continue;
}
if (viewSettings.isHideEmptyMiddlePackages()) {
if (!isEmptyMiddleDirectory(subdir, false)) {
if (!isEmptyMiddleDirectory(subdir, false, filter)) {
container.add(new PsiDirectoryNode(project, subdir, viewSettings));
container.add(new PsiDirectoryNode(project, subdir, viewSettings, filter));
}
}
else {
container.add(new PsiDirectoryNode(project, subdir, viewSettings));
container.add(new PsiDirectoryNode(project, subdir, viewSettings, filter));
}
addAllSubpackages(container, subdir, moduleFileIndex, viewSettings);
addAllSubpackages(container, subdir, moduleFileIndex, viewSettings, filter);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -41,19 +41,35 @@ 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.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.file.PsiDirectoryFactory;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.IconUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
public class PsiDirectoryNode extends BasePsiNode<PsiDirectory> implements NavigatableWithText {
private final PsiFileSystemItemFilter myFilter;
public PsiDirectoryNode(Project project, PsiDirectory value, ViewSettings viewSettings) {
this(project, value, viewSettings, null);
}
public PsiDirectoryNode(Project project, PsiDirectory value, ViewSettings viewSettings, @Nullable PsiFileSystemItemFilter filter) {
super(project, value, viewSettings);
myFilter = filter;
}
@Nullable
public PsiFileSystemItemFilter getFilter() {
return myFilter;
}
protected boolean shouldShowModuleName() {
@@ -140,7 +156,7 @@ public class PsiDirectoryNode extends BasePsiNode<PsiDirectory> implements Navig
@Override
public Collection<AbstractTreeNode> getChildrenImpl() {
return ProjectViewDirectoryHelper.getInstance(myProject).getDirectoryChildren(getValue(), getSettings(), true);
return ProjectViewDirectoryHelper.getInstance(myProject).getDirectoryChildren(getValue(), getSettings(), true, getFilter());
}
@Override
@@ -169,8 +185,17 @@ public class PsiDirectoryNode extends BasePsiNode<PsiDirectory> implements Navig
return false;
}
final Project project = value.getProject();
PsiFileSystemItemFilter filter = getFilter();
if (filter != null) {
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile != null && !filter.shouldShow(psiFile)) return false;
PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(file);
if (psiDirectory != null && !filter.shouldShow(psiDirectory)) 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);
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2016 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.projectView.ViewSettings;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import org.jetbrains.annotations.NotNull;
public interface PsiFileSystemItemFilter {
/**
* @param item {@link PsiFile file} or {@link PsiDirectory directory}.
* @return <code>true</code> if item should be showed in project view, otherwise <code>false</code>.
* @see ProjectViewDirectoryHelper#getDirectoryChildren(PsiDirectory, ViewSettings, boolean, PsiFileSystemItemFilter)
*/
boolean shouldShow(@NotNull PsiFileSystemItem item);
}
@@ -19,10 +19,7 @@ import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.TreeStructureProvider;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.ProjectRootsUtil;
import com.intellij.ide.projectView.impl.nodes.ProjectViewModuleGroupNode;
import com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode;
import com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.projectView.impl.nodes.*;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.module.Module;
@@ -204,7 +201,7 @@ public class GradleTreeStructureProvider implements TreeStructureProvider {
final Module module = fileIndex.getModuleForFile(virtualFile);
String sourceSetName = getSourceSetName(module);
if (sourceSetName == null) return null;
return new GradleSourceSetDirectoryNode(project, psiDirectory, settings, module, sourceSetName);
return new GradleSourceSetDirectoryNode(project, psiDirectory, settings, module, sourceSetName, directoryNode.getFilter());
}
@Nullable
@@ -228,8 +225,9 @@ public class GradleTreeStructureProvider implements TreeStructureProvider {
PsiDirectory psiDirectory,
ViewSettings settings,
Module module,
String sourceSetName) {
super(project, psiDirectory, settings);
String sourceSetName,
PsiFileSystemItemFilter filter) {
super(project, psiDirectory, settings, filter);
mySourceSetName = sourceSetName;
myModule = module;
}