/* * 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.nodeEditor; import com.intellij.ide.DataManager; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.ui.awt.RelativePoint; import jetbrains.mps.ide.icons.IconManager; import jetbrains.mps.nodeEditor.cells.EditorCell_Error; import jetbrains.mps.nodeEditor.cells.EditorCell_Label; import jetbrains.mps.openapi.editor.cells.EditorCell; import jetbrains.mps.smodel.SLanguageHierarchy; import jetbrains.mps.smodel.SModelOperations; import jetbrains.mps.smodel.action.NodeFactoryManager; import jetbrains.mps.smodel.language.ConceptRegistry; import jetbrains.mps.smodel.language.LanguageRegistry; import jetbrains.mps.util.Setter; import jetbrains.mps.util.ToStringComparator; import jetbrains.mps.workbench.action.BaseAction; import jetbrains.mps.workbench.action.BaseGroup; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.mps.openapi.language.SAbstractConcept; import org.jetbrains.mps.openapi.language.SConcept; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.model.SModel; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.util.Condition; import java.awt.Component; import java.awt.Point; import java.util.Arrays; import java.util.Map; import java.util.Set; public final class CreateFromUsageUtil { private CreateFromUsageUtil() { } public static boolean isApplicable(jetbrains.mps.openapi.editor.EditorContext editorContext) { boolean applicable = false; EditorCell selectedCell = editorContext.getSelectedCell(); if (selectedCell instanceof EditorCell_Error) { EditorCell_Label editorCell_Label = (EditorCell_Label) selectedCell; applicable = editorCell_Label.getText().length() > 0; } return applicable; } public static String getText(jetbrains.mps.openapi.editor.EditorContext editorContext) { EditorCell cell = editorContext.getSelectedCell(); if (cell instanceof EditorCell_Label) { return ((EditorCell_Label) cell).getText(); } return null; } public static void showCreateNewRootMenu(@NotNull jetbrains.mps.openapi.editor.EditorContext editorContext, @Nullable Setter<SNode> newRootHandler, @Nullable Condition<SConcept> conceptsFilter) { final EditorCell selectedCell = editorContext.getSelectedCell(); int x = selectedCell.getX(); int y = selectedCell.getY(); if (selectedCell instanceof EditorCell_Label) { y += selectedCell.getHeight(); } Component editorComponent = ((EditorContext) editorContext).getNodeEditorComponent(); final DataContext dataContext = DataManager.getInstance().getDataContext(editorComponent, x, y); final SModel model = selectedCell.getSNode().getModel(); if (conceptsFilter == null) { conceptsFilter = Condition.TRUE_CONDITION; } BaseGroup group = new BaseGroup(""); Set<SLanguage> modelLanguages = new SLanguageHierarchy(SModelOperations.getAllLanguageImports(model)).getExtended(); SLanguage[] languages = modelLanguages.toArray(new SLanguage[modelLanguages.size()]); Arrays.sort(languages, new ToStringComparator()); for (SLanguage language : languages) { boolean hasChildren = false; for (SAbstractConcept ac : language.getConcepts()) { if (!(ac instanceof SConcept)) { continue; } final SConcept concept = (SConcept) ac; if (concept.isRootable() && conceptsFilter.met(concept)) { group.add(new AddNewRootAction(model, concept, newRootHandler)); hasChildren = true; } } if (hasChildren) { group.addSeparator(); } } ListPopup popup = JBPopupFactory.getInstance().createActionGroupPopup(IdeBundle.message("title.popup.new.element"), group, dataContext, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false); // popup.showInBestPositionFor(dataContext); popup.show(new RelativePoint(editorComponent, new Point(x, y))); } private static class AddNewRootAction extends BaseAction { private final SModel myModel; private final SConcept myConcept; private final Setter<SNode> myNewRootCallback; public AddNewRootAction(@NotNull SModel model, @NotNull SConcept concept, @Nullable Setter<SNode> newRootCallback) { myModel = model; myConcept = concept; myNewRootCallback = newRootCallback; setExecuteOutsideCommand(false); final Presentation tp = getTemplatePresentation(); tp.setText(concept.getConceptAlias().isEmpty() ? concept.getName() : concept.getConceptAlias()); tp.setIcon(IconManager.getIcon(concept)); } @Override protected void doExecute(AnActionEvent e, Map<String, Object> params) { SNode result = NodeFactoryManager.createNode(myConcept, null, null, myModel); myModel.addRootNode(result); if (myNewRootCallback != null) { myNewRootCallback.set(result); } } } }