diff --git a/python/src/com/jetbrains/python/projectView/PySkeletonsNode.java b/python/src/com/jetbrains/python/projectView/PySkeletonsNode.java new file mode 100644 index 000000000000..4bdab7626057 --- /dev/null +++ b/python/src/com/jetbrains/python/projectView/PySkeletonsNode.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 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.jetbrains.python.projectView; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.util.PlatformIcons; +import com.jetbrains.python.sdk.PythonSdkType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author vlan + */ +public class PySkeletonsNode extends PsiDirectoryNode { + private PySkeletonsNode(Project project, PsiDirectory value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + @Override + protected void updateImpl(PresentationData data) { + data.setPresentableText("Binary Skeletons"); + data.setIcon(PlatformIcons.LIBRARY_ICON); + } + + @Nullable + public static PySkeletonsNode create(@NotNull Project project, @NotNull Sdk sdk, ViewSettings settings) { + final VirtualFile skeletonsVirtualFile = PythonSdkType.findSkeletonsDir(sdk); + if (skeletonsVirtualFile != null) { + final PsiDirectory skeletonsDirectory = PsiManager.getInstance(project).findDirectory(skeletonsVirtualFile); + return new PySkeletonsNode(project, skeletonsDirectory, settings); + } + return null; + } +} diff --git a/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java b/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java index cb9e2577e1f8..7b711a3923e6 100644 --- a/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java +++ b/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java @@ -17,22 +17,28 @@ package com.jetbrains.python.projectView; import com.intellij.ide.projectView.SelectableTreeStructureProvider; import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.NamedLibraryElement; import com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode; import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; import com.intellij.ide.projectView.impl.nodes.PsiFileNode; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.SdkTypeId; import com.intellij.openapi.roots.JdkOrderEntry; import com.intellij.openapi.roots.LibraryOrSdkOrderEntry; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; +import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil; import com.jetbrains.python.psi.PyDocStringOwner; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.sdk.PythonSdkType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; @@ -45,14 +51,25 @@ public class PyTreeStructureProvider implements SelectableTreeStructureProvider, @NotNull @Override public Collection modify(@NotNull AbstractTreeNode parent, @NotNull Collection children, ViewSettings settings) { - if (parent instanceof NamedLibraryElementNode) { - return hideSkeletons((NamedLibraryElementNode)parent, children); + final Project project = parent.getProject(); + final Sdk sdk = getPythonSdk(parent); + if (sdk != null && project != null) { + final Collection newChildren = hideSkeletons(children); + final PySkeletonsNode skeletonsNode = PySkeletonsNode.create(project, sdk, settings); + if (skeletonsNode != null) { + newChildren.add(skeletonsNode); + } + final PyUserSkeletonsNode userSkeletonsNode = PyUserSkeletonsNode.create(project, settings); + if (userSkeletonsNode != null) { + newChildren.add(userSkeletonsNode); + } + return newChildren; } if (settings.isShowMembers()) { List newChildren = new ArrayList(); for (AbstractTreeNode child : children) { if (child instanceof PsiFileNode && ((PsiFileNode)child).getValue() instanceof PyFile) { - newChildren.add(new PyFileNode(parent.getProject(), ((PsiFileNode)child).getValue(), settings)); + newChildren.add(new PyFileNode(project, ((PsiFileNode)child).getValue(), settings)); } else { newChildren.add(child); @@ -63,23 +80,41 @@ public class PyTreeStructureProvider implements SelectableTreeStructureProvider, return children; } - protected Collection hideSkeletons(NamedLibraryElementNode parent, Collection children) { - LibraryOrSdkOrderEntry orderEntry = parent.getValue().getOrderEntry(); - if (orderEntry instanceof JdkOrderEntry) { - List newChildren = new ArrayList(); - for (AbstractTreeNode child : children) { - if (child instanceof PsiDirectoryNode) { - PsiDirectory directory = ((PsiDirectoryNode)child).getValue(); - PsiDirectory dirParent = directory.getParent(); - if (dirParent != null && dirParent.getName().equals(PythonSdkType.SKELETON_DIR_NAME)) { - continue; + @Nullable + private static Sdk getPythonSdk(@NotNull AbstractTreeNode node) { + if (node instanceof NamedLibraryElementNode) { + final NamedLibraryElement value = ((NamedLibraryElementNode)node).getValue(); + if (value != null) { + final LibraryOrSdkOrderEntry entry = value.getOrderEntry(); + if (entry instanceof JdkOrderEntry) { + final Sdk sdk = ((JdkOrderEntry)entry).getJdk(); + final SdkTypeId type = sdk.getSdkType(); + if (type instanceof PythonSdkType) { + return sdk; } } - newChildren.add(child); } - return newChildren; } - return children; + return null; + } + + @NotNull + private static Collection hideSkeletons(@NotNull Collection children) { + List newChildren = new ArrayList(); + for (AbstractTreeNode child : children) { + if (child instanceof PsiDirectoryNode) { + PsiDirectory directory = ((PsiDirectoryNode)child).getValue(); + if (directory.getVirtualFile().equals(PyUserSkeletonsUtil.getUserSkeletonsDirectory())) { + continue; + } + PsiDirectory dirParent = directory.getParent(); + if (dirParent != null && dirParent.getName().equals(PythonSdkType.SKELETON_DIR_NAME)) { + continue; + } + } + newChildren.add(child); + } + return newChildren; } @Override diff --git a/python/src/com/jetbrains/python/projectView/PyUserSkeletonsNode.java b/python/src/com/jetbrains/python/projectView/PyUserSkeletonsNode.java new file mode 100644 index 000000000000..cff419ca4ac2 --- /dev/null +++ b/python/src/com/jetbrains/python/projectView/PyUserSkeletonsNode.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2014 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.jetbrains.python.projectView; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; +import com.intellij.util.PlatformIcons; +import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author vlan + */ +public class PyUserSkeletonsNode extends PsiDirectoryNode { + private PyUserSkeletonsNode(Project project, PsiDirectory value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + @Override + protected void updateImpl(PresentationData data) { + data.setPresentableText("Extended Definitions"); + data.setIcon(PlatformIcons.LIBRARY_ICON); + } + + @Nullable + public static PyUserSkeletonsNode create(@NotNull Project project, ViewSettings viewSettings) { + final VirtualFile userSkeletonsVirtualFile = PyUserSkeletonsUtil.getUserSkeletonsDirectory(); + if (userSkeletonsVirtualFile != null) { + final PsiDirectory userSkeletonsDirectory = PsiManager.getInstance(project).findDirectory(userSkeletonsVirtualFile); + return new PyUserSkeletonsNode(project, userSkeletonsDirectory, viewSettings); + } + return null; + } +}