@NotNull @Override public Collection<AbstractTreeNode> modify( @NotNull final AbstractTreeNode node, @NotNull Collection<AbstractTreeNode> collection, ViewSettings settings) { final Project project = node.getProject(); if (node instanceof PsiDirectoryNode && project != null) { final Module module = ModuleUtil.findModuleForPsiElement(((PsiDirectoryNode) node).getValue()); final Optional<String> buildPath = module != null ? PantsUtil.getPathFromAddress( module, ExternalSystemConstants.LINKED_PROJECT_PATH_KEY) : Optional.empty(); if (buildPath.isPresent()) { final Optional<VirtualFile> buildFile = PantsUtil.findFileRelativeToBuildRoot(project, buildPath.get()); boolean isModuleRoot = ArrayUtil.indexOf( ModuleRootManager.getInstance(module).getContentRoots(), ((PsiDirectoryNode) node).getVirtualFile()) >= 0; if (buildFile.isPresent() && isModuleRoot) { // Check if there's already a BUILD file in the directory; if so, we don't add another final AbstractTreeNode existingBuildFile = ContainerUtil.find( collection.iterator(), new Condition<AbstractTreeNode>() { @Override public boolean value(AbstractTreeNode node) { return node instanceof PsiFileNode && buildFile.get().equals(((PsiFileNode) node).getVirtualFile()); } }); if (existingBuildFile == null) { final PsiFile buildPsiFile = PsiManager.getInstance(project).findFile(buildFile.get()); final PsiFileNode buildNode = new PsiFileNode(project, buildPsiFile, settings) { @Override protected void updateImpl(PresentationData data) { super.updateImpl(data); data.setIcon(PantsIcons.Icon); } }; final List<AbstractTreeNode> modifiedCollection = new ArrayList<AbstractTreeNode>(collection); modifiedCollection.add(buildNode); return modifiedCollection; } } } } return collection; }
protected boolean isCourseBasedProject(@NotNull final AbstractTreeNode parent) { final Project project = parent.getProject(); if (project != null) { final StudyTaskManager studyTaskManager = StudyTaskManager.getInstance(project); if (studyTaskManager.getCourse() == null) { return false; } } return true; }
private <T> T getProvider( Collection<AbstractTreeNode> selected, ProviderFactory<T> createProvider) { if (selected.size() == 0) return null; List<SNodeReference> selectedNodePointers = new ArrayList<SNodeReference>(); Project project = null; EditableSModel modelDescriptor = null; for (AbstractTreeNode treeNode : selected) { if (!(treeNode instanceof MPSPsiElementTreeNode)) return null; // only root nodes please MPSPsiRootNode mpsPsiNode = ((MPSPsiElementTreeNode) treeNode).getValue(); if (!mpsPsiNode.isValid()) return null; selectedNodePointers.add(mpsPsiNode.getSNodeReference()); if (project == null) { project = treeNode.getProject(); } else if (project != treeNode.getProject()) { return null; // only same project } if (modelDescriptor == null) { modelDescriptor = getModel(mpsPsiNode); } else if (modelDescriptor != getModel(mpsPsiNode)) { return null; // only same model } } jetbrains.mps.project.Project mpsProject = ProjectHelper.toMPSProject(project); if (mpsProject == null || modelDescriptor == null) return null; SModel sModel = modelDescriptor; if (sModel == null) return null; return createProvider.create(selectedNodePointers, modelDescriptor, sModel, mpsProject); }
private <T> T getModelProvider( AbstractTreeNode treeNode, ModelProviderFactory<T> createProvider) { if (!(treeNode instanceof MPSPsiModelTreeNode)) return null; // only model MPSPsiModel psiModel = ((MPSPsiModelTreeNode) treeNode).getModel(); if (psiModel == null || !psiModel.isValid()) return null; Project project = treeNode.getProject(); EditableSModel modelDescriptor = getModel(treeNode); jetbrains.mps.project.Project mpsProject = ProjectHelper.toMPSProject(project); if (mpsProject == null || modelDescriptor == null) return null; SModel sModel = modelDescriptor; if (sModel == null) return null; return createProvider.create(modelDescriptor, sModel, mpsProject); }
@NotNull @Override public Collection<AbstractTreeNode> modify( @NotNull AbstractTreeNode parent, @NotNull Collection<AbstractTreeNode> children, ViewSettings settings) { if (!isCourseBasedProject(parent)) { return children; } Collection<AbstractTreeNode> nodes = new ArrayList<AbstractTreeNode>(); for (AbstractTreeNode node : children) { final Project project = node.getProject(); if (project != null) { if (node.getValue() instanceof PsiDirectory) { final PsiDirectory nodeValue = (PsiDirectory) node.getValue(); if (!nodeValue.getName().contains(EduNames.USER_TESTS) && !nodeValue.getName().equals(".idea")) { StudyDirectoryNode newNode = new StudyDirectoryNode(project, nodeValue, settings); nodes.add(newNode); } } else { if (parent instanceof StudyDirectoryNode && node instanceof PsiFileNode) { final PsiFileNode psiFileNode = (PsiFileNode) node; final VirtualFile virtualFile = psiFileNode.getVirtualFile(); if (virtualFile == null) { return nodes; } final TaskFile taskFile = StudyUtils.getTaskFile(project, virtualFile); if (taskFile != null) { nodes.add(node); } final String parentName = parent.getName(); if (parentName != null) { if (parentName.equals(EduNames.SANDBOX_DIR)) { nodes.add(node); } } } } } } return nodes; }
private SNode getNode(AbstractTreeNode treeNode) { if (!(treeNode instanceof MPSPsiElementTreeNode)) { return null; } MPSPsiNodeBase psiNode = ((MPSPsiElementTreeNode) treeNode).getValue(); if (!(psiNode instanceof MPSPsiRealNode)) { return null; } final SNodeReference nodeRef = ((MPSPsiRealNode) psiNode).getSNodeReference(); final SRepository repository = ProjectHelper.getProjectRepository(treeNode.getProject()); // TODO remove read action from here once SModelFileTracker stops doing the same (creating read // action if not already in one) return new ModelComputeRunnable<SNode>( new Computable<SNode>() { @Override public SNode compute() { return nodeRef.resolve(repository); } }) .runRead(repository.getModelAccess()); }
@Override public Collection<AbstractTreeNode> modify( final AbstractTreeNode treeNode, final Collection<AbstractTreeNode> children, final ViewSettings settings) { final Ref<Collection<AbstractTreeNode>> result = new Ref<Collection<AbstractTreeNode>>(children); // we're actually in EDT here, but we work with SModels, and various routines assert that we can // read, thus read action ProjectHelper.getProjectRepository(treeNode.getProject()) .getModelAccess() .runReadAction( new Runnable() { @Override public void run() { List<AbstractTreeNode> updatedChildren = null; final MPSPsiProvider mpsPsiProvider = MPSPsiProvider.getInstance(treeNode.getProject()); // if current dir is data source from some model FolderDataSource currentDirectoryDataSource = null; if (treeNode instanceof PsiDirectoryNode) { // let's see if we have a model built from this dir, e.g. in per-root persistence SModel sModel = SModelFileTracker.getInstance() .findModel( VirtualFileUtils.toIFile( ((PsiDirectoryNode) treeNode).getVirtualFile())); if (sModel != null) { // adding root nodes (removing their corresponding files' nodes from the tree is // further below) List<MPSPsiElementTreeNode> rootsTreeNodes = new ArrayList<MPSPsiElementTreeNode>(); for (SNode root : sModel.getRootNodes()) { rootsTreeNodes.add( new MPSPsiElementTreeNode( treeNode.getProject(), (MPSPsiRootNode) mpsPsiProvider.getPsi(root).getContainingFile(), settings)); } if (!rootsTreeNodes.isEmpty() && updatedChildren == null) { updatedChildren = new ArrayList<AbstractTreeNode>(children); updatedChildren.addAll(rootsTreeNodes); } DataSource dataSource = sModel.getSource(); if (dataSource instanceof FolderDataSource) { // could be assert as currently SModelFileTracker only tracks FileDataSource // and FolderDataSource currentDirectoryDataSource = (FolderDataSource) dataSource; } } } else if (treeNode instanceof MPSPsiModelTreeNode) { MPSPsiModel psiModel = ((MPSPsiModelTreeNode) treeNode).extractPsiFromValue(); updatedChildren = new ArrayList<AbstractTreeNode>(); for (PsiElement psiElement : psiModel.getChildren()) { updatedChildren.add( new MPSPsiElementTreeNode( treeNode.getProject(), (MPSPsiRootNode) psiElement, settings)); } } for (final AbstractTreeNode child : children) { if (child instanceof PsiFileNode) { VirtualFile vFile = ((PsiFileNode) child).getVirtualFile(); if (vFile == null) { continue; } // check if it's a single file model final SModel sModel = SModelFileTracker.getInstance().findModel(VirtualFileUtils.toIFile(vFile)); if (sModel != null) { if (updatedChildren == null) updatedChildren = new ArrayList<AbstractTreeNode>(children); int idx = updatedChildren.indexOf(child); updatedChildren.remove(idx); updatedChildren.add( idx, new MPSPsiModelTreeNode( treeNode.getProject(), mpsPsiProvider.getPsi(sModel), settings)); continue; } if (currentDirectoryDataSource != null && currentDirectoryDataSource.isIncluded(VirtualFileUtils.toIFile(vFile))) { // it's a file that constitutes a FolderDataSource-backed model, remove it // from the tree (root nodes are shown instead) if (updatedChildren == null) updatedChildren = new ArrayList<AbstractTreeNode>(children); int idx = updatedChildren.indexOf(child); updatedChildren.remove(idx); } } else if (child instanceof PsiDirectoryNode) { // below code only attaches our action to the directory and makes it show added // children - our root nodes final SModel perRootModel = SModelFileTracker.getInstance() .findModel( VirtualFileUtils.toIFile( ((PsiDirectoryNode) child).getVirtualFile())); if (perRootModel != null) { if (updatedChildren == null) updatedChildren = new ArrayList<AbstractTreeNode>(children); int idx = updatedChildren.indexOf(child); updatedChildren.remove(idx); updatedChildren.add( idx, new PsiDirectoryNode( treeNode.getProject(), ((PsiDirectoryNode) child).getValue(), settings) { @Override public boolean canNavigate() { return true; } @Override public String getNavigateActionText(boolean focusEditor) { return MPSBundle.message("open.model.properties.action"); } @Override public void navigate(boolean requestFocus) { MPSPropertiesConfigurable configurable = new ModelPropertiesConfigurable( perRootModel, ProjectHelper.toMPSProject(myProject), true); final SingleConfigurableEditor dialog = new SingleConfigurableEditor(myProject, configurable); configurable.setParentForCallBack(dialog); SwingUtilities.invokeLater( new Runnable() { @Override public void run() { dialog.show(); } }); } }); } } } if (updatedChildren != null) { result.set(updatedChildren); } } }); return result.get(); }
private Module getIdeaModule(AbstractTreeNode treeNode) { VirtualFile modelVFile = getVirtualFile(treeNode); if (modelVFile == null) return null; return ModuleUtilCore.findModuleForFile(modelVFile, treeNode.getProject()); }