From bbe329877d8ef74f237332265242da2d595a6798 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 9 Sep 2009 21:22:45 +0400 Subject: [PATCH] file based project view implementation --- .../impl/JavaProjectViewDirectoryHelper.java | 12 +- .../FavoritesTreeNodeDescriptor.java | 6 +- .../ide/projectView/impl/NamedLibraryUrl.java | 13 +-- .../ide/projectView/impl/ProjectViewImpl.java | 29 ++++- .../impl/nodes/ExternalLibrariesNode.java | 109 ++++++++++++++++++ .../impl/nodes/LibraryGroupNode.java | 7 +- .../impl/nodes/NamedLibraryElement.java | 16 +-- .../nodes/ProjectViewDirectoryHelper.java | 17 +-- .../impl/nodes/ProjectViewProjectNode.java | 26 ++++- .../impl/nodes/PsiDirectoryNode.java | 67 ++++++++--- .../projectView/impl/nodes/PsiFileNode.java | 26 +++++ .../src/messages/IdeBundle.properties | 1 + 12 files changed, 271 insertions(+), 58 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ExternalLibrariesNode.java diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/JavaProjectViewDirectoryHelper.java b/java/java-impl/src/com/intellij/ide/projectView/impl/JavaProjectViewDirectoryHelper.java index f807bc4c5774..5829877ed630 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/JavaProjectViewDirectoryHelper.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/JavaProjectViewDirectoryHelper.java @@ -50,16 +50,6 @@ public class JavaProjectViewDirectoryHelper extends ProjectViewDirectoryHelper { public String getNodeName(final ViewSettings settings, final Object parentValue, final PsiDirectory directory) { PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory); - if (aPackage != null - && !ProjectRootsUtil.isSourceRoot(directory) - && !settings.isFlattenPackages() - && settings.isHideEmptyMiddlePackages() - && !ProjectRootsUtil.isLibraryRoot(directory.getVirtualFile(), getProject()) - && TreeViewUtil.isEmptyMiddlePackage(directory, true)) { - return null; - } - - PsiPackage parentPackage; if (!ProjectRootsUtil.isSourceRoot(directory) && aPackage != null && aPackage.getQualifiedName().length() > 0 && parentValue instanceof PsiDirectory) { @@ -108,4 +98,4 @@ public class JavaProjectViewDirectoryHelper extends ProjectViewDirectoryHelper { } return false; } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java index 1850a23d26a2..0f414ec96f38 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java @@ -7,6 +7,7 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.ide.util.treeView.PresentableNodeDescriptor; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; @@ -58,9 +59,10 @@ public class FavoritesTreeNodeDescriptor extends PresentableNodeDescriptor myOptionsMap; private final boolean myOptionDefaultValue; @@ -1022,7 +1023,15 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat } if (DataConstants.MODULE_CONTEXT.equals(dataId)) { Object selected = getSelectedNodeElement(); - return selected instanceof Module ? selected : null; + if (selected instanceof Module) { + return !((Module)selected).isDisposed() ? selected : null; + } + else if (selected instanceof VirtualFile) { + return moduleByContentRoot((VirtualFile)selected); + } + else { + return null; + } } if (DataConstants.MODULE_CONTEXT_ARRAY.equals(dataId)) { @@ -1116,7 +1125,12 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat Collection modules = ((ModuleGroup)element).modulesInGroup(myProject, true); result.addAll(modules); } + else if (element instanceof VirtualFile) { + Module module = moduleByContentRoot((VirtualFile)element); + if (module != null) result.add(module); + } } + if (result.isEmpty()) { return null; } @@ -1126,6 +1140,17 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat } } + private Module moduleByContentRoot(VirtualFile file) { + if (ProjectRootsUtil.isModuleContentRoot(file, myProject)) { + Module module = ProjectRootManager.getInstance(myProject).getFileIndex().getModuleForFile(file); + if (module != null && !module.isDisposed()) { + return module; + } + } + + return null; + } + private List getSelectedElements(Class klass) { ArrayList result = new ArrayList(); final AbstractProjectViewPane viewPane = getCurrentProjectViewPane(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ExternalLibrariesNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ExternalLibrariesNode.java new file mode 100644 index 000000000000..559c05d45564 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ExternalLibrariesNode.java @@ -0,0 +1,109 @@ +/* + * @author max + */ +package com.intellij.ide.projectView.impl.nodes; + +import com.intellij.ide.IdeBundle; +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.util.Icons; +import com.intellij.util.PathUtil; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +public class ExternalLibrariesNode extends ProjectViewNode { + public ExternalLibrariesNode(Project project, ViewSettings viewSettings) { + super(project, "External Libraries", viewSettings); + } + + @Override + public boolean contains(@NotNull VirtualFile file) { + return someChildContainsFile(file); + } + + @NotNull + @Override + public Collection getChildren() { + final List children = new ArrayList(); + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(getProject()).getFileIndex(); + Module[] modules = ModuleManager.getInstance(getProject()).getModules(); + Set processedLibraries = new THashSet(); + Set processedSdk = new THashSet(); + + for (Module module : modules) { + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + final OrderEntry[] orderEntries = moduleRootManager.getOrderEntries(); + for (final OrderEntry orderEntry : orderEntries) { + if (orderEntry instanceof LibraryOrderEntry) { + final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry; + final Library library = libraryOrderEntry.getLibrary(); + if (library == null) continue; + if (processedLibraries.contains(library)) continue; + processedLibraries.add(library); + + if (!hasExternalEntries(fileIndex, libraryOrderEntry)) continue; + + final String libraryName = library.getName(); + if (libraryName == null || libraryName.length() == 0) { + addLibraryChildren(orderEntry, children, getProject(), this); + } + else { + children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(null, orderEntry), getSettings())); + } + } + else if (orderEntry instanceof JdkOrderEntry) { + final Sdk jdk = ((JdkOrderEntry)orderEntry).getJdk(); + if (jdk != null) { + if (processedSdk.contains(jdk)) continue; + processedSdk.add(jdk); + children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(null, orderEntry), getSettings())); + } + } + } + } + return children; + } + + public static void addLibraryChildren(final OrderEntry entry, final List children, Project project, ProjectViewNode node) { + final PsiManager psiManager = PsiManager.getInstance(project); + final VirtualFile[] files = entry.getFiles(OrderRootType.CLASSES); + for (final VirtualFile file : files) { + final PsiDirectory psiDir = psiManager.findDirectory(file); + if (psiDir == null) { + continue; + } + children.add(new PsiDirectoryNode(project, psiDir, node.getSettings())); + } + } + + private static boolean hasExternalEntries(ProjectFileIndex index, OrderEntry orderEntry) { + VirtualFile[] files = orderEntry.getFiles(OrderRootType.CLASSES); + for (VirtualFile file : files) { + if (!index.isInContent(PathUtil.getLocalFile(file))) return true; + } + + return false; + } + + @Override + protected void update(PresentationData presentation) { + presentation.setPresentableText(IdeBundle.message("node.projectview.external.libraries")); + presentation.setIcons(Icons.LIBRARY_ICON); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java index 75c8f4e96de4..68e35003271d 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupNode.java @@ -33,7 +33,8 @@ public class LibraryGroupNode extends ProjectViewNode { @NotNull public Collection getChildren() { - final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(getValue().getModule()); + Module module = getValue().getModule(); + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); final List children = new ArrayList(); final OrderEntry[] orderEntries = moduleRootManager.getOrderEntries(); for (final OrderEntry orderEntry : orderEntries) { @@ -48,13 +49,13 @@ public class LibraryGroupNode extends ProjectViewNode { addLibraryChildren(orderEntry, children, getProject(), this); } else { - children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(getValue(), orderEntry), getSettings())); + children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(module, orderEntry), getSettings())); } } else if (orderEntry instanceof JdkOrderEntry) { final Sdk jdk = ((JdkOrderEntry)orderEntry).getJdk(); if (jdk != null) { - children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(getValue(), orderEntry), getSettings())); + children.add(new NamedLibraryElementNode(getProject(), new NamedLibraryElement(module, orderEntry), getSettings())); } } } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java index 777196c39c7c..a794b984c539 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java @@ -1,6 +1,8 @@ package com.intellij.ide.projectView.impl.nodes; +import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.util.Comparing; /** * @author Eugene Zhuravlev @@ -8,16 +10,16 @@ import com.intellij.openapi.roots.OrderEntry; * Time: 7:08:30 PM */ public final class NamedLibraryElement { - private final LibraryGroupElement myParent; + private final Module myContextModule; private final OrderEntry myEntry; - public NamedLibraryElement(LibraryGroupElement parent, OrderEntry entry) { - myParent = parent; + public NamedLibraryElement(Module parent, OrderEntry entry) { + myContextModule = parent; myEntry = entry; } - public LibraryGroupElement getParent() { - return myParent; + public Module getModule() { + return myContextModule; } public String getName() { @@ -31,14 +33,14 @@ public final class NamedLibraryElement { final NamedLibraryElement namedLibraryElement = (NamedLibraryElement)o; if (!myEntry.equals(namedLibraryElement.myEntry)) return false; - if (!myParent.equals(namedLibraryElement.myParent)) return false; + if (Comparing.equal(myContextModule, namedLibraryElement.myContextModule)) return false; return true; } public int hashCode() { int result; - result = myParent.hashCode(); + result = myContextModule != null ? myContextModule.hashCode() : 0; result = 29 * result + myEntry.hashCode(); return result; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java index d2286475d7a6..f52becf211ef 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java @@ -99,12 +99,12 @@ public class ProjectViewDirectoryHelper { final ViewSettings settings, final boolean withSubDirectories) { final List children = new ArrayList(); - final Project project = psiDirectory.getProject(); + final Project project = psiDirectory.getProject(); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); final Module module = fileIndex.getModuleForFile(psiDirectory.getVirtualFile()); final ModuleFileIndex moduleFileIndex = module == null ? null : ModuleRootManager.getInstance(module).getFileIndex(); if (!settings.isFlattenPackages() || skipDirectory(psiDirectory)) { - processPsiDirectoryChildren(psiDirectory, psiDirectory.getChildren(), children, fileIndex, moduleFileIndex, settings, + processPsiDirectoryChildren(psiDirectory, psiDirectory.getChildren(), children, fileIndex, null, settings, withSubDirectories); } else { // source directory in "flatten packages" mode @@ -117,11 +117,9 @@ public class ProjectViewDirectoryHelper { if (!skipDirectory(subdir)) { continue; } - if (moduleFileIndex != null) { - if (!moduleFileIndex.isInContent(subdir.getVirtualFile())) { - continue; - } - } + VirtualFile directoryFile = subdir.getVirtualFile(); + if (fileIndex.isIgnored(directoryFile)) continue; + if (withSubDirectories) { children.add(new PsiDirectoryNode(project, subdir, settings)); } @@ -183,6 +181,7 @@ public class ProjectViewDirectoryHelper { if (moduleFileIndex != null && !moduleFileIndex.isInContent(vFile)) { return; } + /* final boolean childInLibraryClasses = projectFileIndex.isInLibraryClasses(vFile); if (!projectFileIndex.isInSourceContent(vFile)) { if (childInLibraryClasses) { @@ -197,6 +196,7 @@ public class ProjectViewDirectoryHelper { if (childInLibraryClasses && !projectFileIndex.isInContent(vFile) && !showFileInLibClasses(vFile)) { return; // skip java sources in classpath } + */ try { container.add(ProjectViewNode.createTreeNode(nodeClass, element.getProject(), element, settings)); @@ -219,6 +219,7 @@ public class ProjectViewDirectoryHelper { } if (moduleFileIndex != null) { if (!moduleFileIndex.isInContent(subdir.getVirtualFile())) { + container.add(new PsiDirectoryNode(project, subdir, viewSettings)); continue; } } @@ -234,4 +235,4 @@ public class ProjectViewDirectoryHelper { addAllSubpackages(container, subdir, moduleFileIndex, viewSettings); } } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java index 693b352bf9d3..291ec4879b99 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java @@ -4,9 +4,10 @@ import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; @@ -23,13 +24,23 @@ public class ProjectViewProjectNode extends AbstractProjectNode { @NotNull public Collection getChildren() { - final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); - final ArrayList nodes = new ArrayList(); - nodes.addAll(modulesAndGroups(modules)); + final PsiManager psiManager = PsiManager.getInstance(getProject()); + ProjectRootManager prm = ProjectRootManager.getInstance(getProject()); + ProjectFileIndex index = prm.getFileIndex(); + + ArrayList nodes = new ArrayList(); + + for (VirtualFile root : prm.getContentRoots()) { + VirtualFile parent = root.getParent(); + if (parent == null || !index.isInContent(parent)) { + nodes.add(new PsiDirectoryNode(getProject(), psiManager.findDirectory(root), getSettings())); + } + } + + final VirtualFile baseDir = getProject().getBaseDir(); if (baseDir == null) return nodes; - final PsiManager psiManager = PsiManager.getInstance(getProject()); final VirtualFile[] files = baseDir.getChildren(); for (VirtualFile file : files) { if (ModuleUtil.findModuleForFile(file, getProject()) == null) { @@ -38,6 +49,11 @@ public class ProjectViewProjectNode extends AbstractProjectNode { } } } + + if (getSettings().isShowLibraryContents()) { + nodes.add(new ExternalLibrariesNode(getProject(), getSettings())); + } + return nodes; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java index f43de0d89960..ade1420bb62e 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java @@ -9,18 +9,19 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleFileIndex; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.impl.file.PsiDirectoryFactory; import com.intellij.ui.LayeredIcon; import com.intellij.util.Icons; +import com.intellij.util.PathUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -35,6 +36,37 @@ public class PsiDirectoryNode extends BasePsiNode { final Project project = getProject(); final PsiDirectory psiDirectory = getValue(); final VirtualFile directoryFile = psiDirectory.getVirtualFile(); + + if (ProjectRootsUtil.isModuleContentRoot(directoryFile, project)) { + ProjectFileIndex fi = ProjectRootManager.getInstance(project).getFileIndex(); + Module module = fi.getModuleForFile(directoryFile); + + data.setPresentableText(directoryFile.getName()); + if (module != null) { + data.setOpenIcon(module.getModuleType().getNodeIcon(true)); + data.setClosedIcon(module.getModuleType().getNodeIcon(false)); + + StringBuilder location = new StringBuilder(); + if (getParentValue() instanceof Project) { + location.append(directoryFile.getPresentableUrl()); + } + + if (!Comparing.equal(module.getName(), directoryFile.getName())) { + if (location.length() > 0) { + location.append(", "); + } + + location.append("Module '").append(module.getName()).append("'"); + } + + if (location.length() > 0) { + data.setLocationString(location.toString()); + } + + return; + } + } + final String name = getParentValue() instanceof Project ? psiDirectory.getVirtualFile().getPresentableUrl() : ProjectViewDirectoryHelper.getInstance(psiDirectory.getProject()).getNodeName(getSettings(), getParentValue(), psiDirectory); @@ -89,18 +121,18 @@ public class PsiDirectoryNode extends BasePsiNode { return false; } - if (!VfsUtil.isAncestor(value.getVirtualFile(), file, false)) { + VirtualFile directory = value.getVirtualFile(); + if (directory.getFileSystem() instanceof LocalFileSystem) { + file = PathUtil.getLocalFile(file); + } + + if (!VfsUtil.isAncestor(directory, file, false)) { return false; } + final Project project = value.getProject(); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); - final Module module = fileIndex.getModuleForFile(value.getVirtualFile()); - if (module == null) { - return fileIndex.getModuleForFile(file) == null; - } - final ModuleFileIndex moduleFileIndex = ModuleRootManager.getInstance(module).getFileIndex(); - - return moduleFileIndex.isInContent(file); + return !fileIndex.isIgnored(file); } public VirtualFile getVirtualFile() { @@ -117,8 +149,12 @@ public class PsiDirectoryNode extends BasePsiNode { } public boolean canNavigate() { - VirtualFile virtualFile = getVirtualFile(); - return virtualFile != null && (ProjectRootsUtil.isSourceOrTestRoot(virtualFile, getProject()) || ProjectRootsUtil.isLibraryRoot(virtualFile, getProject())); + VirtualFile file = getVirtualFile(); + Project project = getProject(); + + return file != null && (ProjectRootsUtil.isModuleContentRoot(file, project) || + ProjectRootsUtil.isSourceOrTestRoot(file, project) || + ProjectRootsUtil.isLibraryRoot(file, project)); } public boolean canNavigateToSource() { @@ -128,7 +164,12 @@ public class PsiDirectoryNode extends BasePsiNode { public void navigate(final boolean requestFocus) { Module module = ModuleUtil.findModuleForPsiElement(getValue()); if (module != null) { - ProjectSettingsService.getInstance(myProject).openContentEntriesSettings(module); + if (ProjectRootsUtil.isModuleContentRoot(getVirtualFile(), getProject())) { + ProjectSettingsService.getInstance(myProject).openModuleSettings(module); + } + else { + ProjectSettingsService.getInstance(myProject).openContentEntriesSettings(module); + } } } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java index 1aadbf104b96..8698aaa9617b 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java @@ -1,13 +1,19 @@ package com.intellij.ide.projectView.impl.nodes; +import com.intellij.ide.highlighter.ArchiveFileType; import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.util.PathUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -20,9 +26,24 @@ public class PsiFileNode extends BasePsiNode{ } public Collection getChildrenImpl() { + if (isArchive()) { + VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(getVirtualFile()); + if (jarRoot != null) { + PsiDirectory psiDirectory = PsiManager.getInstance(getProject()).findDirectory(jarRoot); + if (psiDirectory != null) { + return ProjectViewDirectoryHelper.getInstance(getProject()).getDirectoryChildren(psiDirectory, getSettings(), true); + } + } + } + return new ArrayList(); } + private boolean isArchive() { + VirtualFile file = getVirtualFile(); + return file != null && file.isValid() && file.getFileType() instanceof ArchiveFileType; + } + protected void updateImpl(PresentationData data) { final PsiFile value = getValue(); data.setPresentableText(value.getName()); @@ -84,4 +105,9 @@ public class PsiFileNode extends BasePsiNode{ public boolean canRepresent(final Object element) { return super.canRepresent(element) || getValue().getVirtualFile() == element; } + + @Override + public boolean contains(@NotNull VirtualFile file) { + return super.contains(file) || isArchive() && PathUtil.getLocalFile(file) == getVirtualFile(); + } } diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 2159c2cb3c04..2b841c9dfc8f 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -569,6 +569,7 @@ command.renaming.module=Renaming module {0} prompt.enter.new.module.name=Enter new module name tooltip.ui.designer.form=UI Designer Form node.projectview.libraries=Libraries +node.projectview.external.libraries=External Libraries tooltip.module.group=Module Group node.projectview.library={0} library node.projectview.jdk=JDK