/* * 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.editorTabs.tabfactory.tabs; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DefaultActionGroup; import jetbrains.mps.ide.editorTabs.tabfactory.NodeChangeCallback; import jetbrains.mps.ide.icons.IconManager; import jetbrains.mps.ide.relations.RelationComparator; import jetbrains.mps.plugins.relations.RelationDescriptor; import jetbrains.mps.project.Project; import jetbrains.mps.smodel.ModelAccessHelper; import jetbrains.mps.smodel.SNodeUtil; import jetbrains.mps.util.Computable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.mps.openapi.language.SConcept; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.openapi.model.SNodeAccessUtil; import org.jetbrains.mps.openapi.model.SNodeReference; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; public class CreateGroupsBuilder { private final Project myProject; private final SNodeReference myBaseNode; private final NodeChangeCallback myCallback; public CreateGroupsBuilder(@NotNull Project mpsProject, @NotNull SNodeReference baseNode, @NotNull NodeChangeCallback callback) { myProject = mpsProject; myBaseNode = baseNode; myCallback = callback; } public List<DefaultActionGroup> getCreateGroups(final Collection<RelationDescriptor> possibleTabs, @Nullable final RelationDescriptor currentAspect) { return new ModelAccessHelper(myProject.getModelAccess()).runReadAction(new Computable<List<DefaultActionGroup>>() { @Override public List<DefaultActionGroup> compute() { List<DefaultActionGroup> groups = new ArrayList<>(); List<RelationDescriptor> tabs = new ArrayList<>(possibleTabs); Collections.sort(tabs, new RelationComparator()); if (currentAspect != null) { tabs.remove(currentAspect); tabs.add(0, currentAspect); } for (final RelationDescriptor d : tabs) { List<SNode> nodes = d.getNodes(myBaseNode.resolve(myProject.getRepository())); if (!nodes.isEmpty() && d.isSingle()) { continue; } DefaultActionGroup group = doGetCreateGroup(d); if (tabs.indexOf(d) == 0) { group.setPopup(false); } groups.add(group); } return groups; } }); } @NotNull public DefaultActionGroup getCreateGroup(final RelationDescriptor d) { return new ModelAccessHelper(myProject.getModelAccess()).runReadAction(() -> doGetCreateGroup(d)); } private DefaultActionGroup doGetCreateGroup(RelationDescriptor d) { Iterable<SConcept> concepts = d.getAspectConcepts(myBaseNode.resolve(myProject.getRepository())); if (!concepts.iterator().hasNext()) { return new DefaultActionGroup(); } DefaultActionGroup group = new DefaultActionGroup(d.getTitle(), true); for (SConcept concept : concepts) { group.add(new CreateAction(concept, d)); } return group; } private class CreateAction extends AnAction { private final SConcept myConcept; private final RelationDescriptor myDescriptor; public CreateAction(SConcept concept, RelationDescriptor descriptor) { //todo pass concepts instead of nodes super(!concept.getConceptAlias().replaceAll("_", "__").isEmpty() ? concept.getConceptAlias().replaceAll("_", "__") : concept.getName(), "", IconManager.getIconFor(concept) ); myConcept = concept; myDescriptor = descriptor; } @Override public void actionPerformed(AnActionEvent e) { // FIXME bloody sh!t, two commands depending on boolean; package name set with a separate command - ORLY? final SNode[] created = new SNode[1]; final Runnable r1 = () -> { SNode node = new ModelAccessHelper(myProject.getModelAccess()).runReadAction(() -> myBaseNode.resolve(myProject.getRepository())); created[0] = myDescriptor.createAspect(node, myConcept); }; final Runnable r2 = () -> { String mainPack = SNodeAccessUtil.getProperty(myBaseNode.resolve(myProject.getRepository()), SNodeUtil.property_BaseConcept_virtualPackage); // TODO: remove this code. Virtual package is specified inside ConceptAspectsHelper class SNodeAccessUtil.setProperty(created[0], SNodeUtil.property_BaseConcept_virtualPackage, mainPack); myCallback.changeNode(created[0].getReference()); }; if (myDescriptor.commandOnCreate()) { myProject.getModelAccess().executeCommand(r1); } else { r1.run(); } if (created[0] == null) { return; } myProject.getModelAccess().executeCommand(r2); } } }