/*
* Copyright 2003-2015 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 jetbrains.mps.ide.ui.tree.module;
import jetbrains.mps.ide.ui.tree.MPSTreeNode;
import jetbrains.mps.ide.ui.tree.TreeElement;
import jetbrains.mps.ide.ui.tree.TreeNodeVisitor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.module.SModule;import jetbrains.mps.project.*;
import jetbrains.mps.project.structure.ProjectStructureModule;
import jetbrains.mps.smodel.Generator;
import jetbrains.mps.smodel.Language;
public abstract class ProjectModuleTreeNode extends MPSTreeNode implements MPSModuleTreeNode, TreeElement {
private final SModule myModule;
public static ProjectModuleTreeNode createFor(Project project, SModule module) {
return createFor(project, module, false);
}
public static ProjectModuleTreeNode createFor(Project project, SModule module, boolean shortNameOnly) {
if (module instanceof Language) {
return new ProjectLanguageTreeNode((Language) module, project, shortNameOnly);
} else if (module instanceof Solution || module instanceof ProjectStructureModule) {
return new ProjectSolutionTreeNode((AbstractModule) module, project, shortNameOnly);
} else if (module instanceof DevKit) {
return new ProjectDevKitTreeNode((DevKit) module, project, false);
} else if (module instanceof Generator) {
return new GeneratorTreeNode((Generator) module, project);
}
return null;
}
protected ProjectModuleTreeNode(@NotNull SModule module) {
super(module.getModuleName());
myModule = module;
}
@NotNull
@Override
public SModule getModule() {
return myModule;
}
@Override
protected void doUpdatePresentation() {
setText(getModuleText());
}
@Override
protected final boolean canBeOpened() {
return false;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void accept(@NotNull TreeNodeVisitor visitor) {
visitor.visitModuleNode(this);
}
/**
* Interface a tree could implement in case it hosts nodes for project modules and would like to override/control
* what child nodes could show up there.
*
* There are different approaches to conditional children in a given node.
* We've got SNodeTreeNode.NodeChildrenProvider to show node structure conditionally.
* Besides, we've got TreeNodeParamProvider that provides same condition in a different way.
* We could also pass a configuration object down to tree nodes, but it's cumbersome given depth of the tree.
* Yet another approach is to cast treeNode.getTree() and ask it for specific configuration values (the simplest one).
* Latter is not always possible as we keep nodes in [mps-ui] but trees that use them in [mps-workbench]
* (this split is questionable itself, and perhaps proper structure might help to deal with configurations).
* Neither is appealing to me, though the one with delegation is most flexible, that's why I stick to it.
* <p/>
* Methods take non-null arguments and return {@code true} to indicate provider completed the structure, and
* {@code false} to indicate client shall go on and populate the node itself (and leave children nodes, if any were
* added by the provider, intact).
*/
public interface ModuleNodeChildrenProvider {
boolean populate(MPSTreeNode treeNode, Language language);
boolean populate(MPSTreeNode treeNode, Solution solution);
boolean populate(MPSTreeNode treeNode, Generator generator);
boolean populate(MPSTreeNode treeNode, DevKit devkit);
}
}