/* * 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.intellij.util.xml.tree.actions; import com.intellij.ide.TypePresentationService; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.psi.xml.XmlFile; import com.intellij.ui.treeStructure.SimpleNode; import com.intellij.util.ReflectionUtil; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomUtil; import com.intellij.util.xml.MergedObject; import com.intellij.util.xml.reflect.DomCollectionChildDescription; import com.intellij.util.xml.tree.BaseDomElementNode; import com.intellij.util.xml.tree.DomElementsGroupNode; import com.intellij.util.xml.tree.DomModelTreeView; import com.intellij.util.xml.ui.actions.AddDomElementAction; import com.intellij.util.xml.ui.actions.DefaultAddAction; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.lang.reflect.Type; import java.util.List; public class AddElementInCollectionAction extends AddDomElementAction { private DomModelTreeView myTreeView; public AddElementInCollectionAction() { } public AddElementInCollectionAction(final DomModelTreeView treeView) { myTreeView = treeView; } protected DomModelTreeView getTreeView(AnActionEvent e) { if (myTreeView != null) return myTreeView; return DomModelTreeView.DATA_KEY.getData(e.getDataContext()); } @Override protected boolean isEnabled(final AnActionEvent e) { final DomModelTreeView treeView = getTreeView(e); final boolean enabled = treeView != null; e.getPresentation().setEnabled(enabled); return enabled; } @Override protected void showPopup(final ListPopup groupPopup, final AnActionEvent e) { if (myTreeView == null) { if (e.getPlace().equals(DomModelTreeView.DOM_MODEL_TREE_VIEW_POPUP)) { groupPopup.showInCenterOf(getTreeView(e).getTree()); } else { groupPopup.showInBestPositionFor(e.getDataContext()); } } else { super.showPopup(groupPopup, e); } } @Override @NotNull protected DomCollectionChildDescription[] getDomCollectionChildDescriptions(final AnActionEvent e) { final DomModelTreeView view = getTreeView(e); SimpleNode node = view.getTree().getSelectedNode(); if (node instanceof BaseDomElementNode) { List<DomCollectionChildDescription> consolidated = ((BaseDomElementNode)node).getConsolidatedChildrenDescriptions(); if (consolidated.size() > 0) { return consolidated.toArray(new DomCollectionChildDescription[consolidated.size()]); } } final DomElementsGroupNode groupNode = getDomElementsGroupNode(view); return groupNode == null ? DomCollectionChildDescription.EMPTY_ARRAY : new DomCollectionChildDescription[]{groupNode.getChildDescription()}; } @Override protected DomElement getParentDomElement(final AnActionEvent e) { final DomModelTreeView view = getTreeView(e); SimpleNode node = view.getTree().getSelectedNode(); if (node instanceof BaseDomElementNode) { if (((BaseDomElementNode)node).getConsolidatedChildrenDescriptions().size() > 0) { return ((BaseDomElementNode)node).getDomElement(); } } final DomElementsGroupNode groupNode = getDomElementsGroupNode(view); return groupNode == null ? null : groupNode.getDomElement(); } @Override protected JComponent getComponent(AnActionEvent e) { return getTreeView(e); } @Override protected boolean showAsPopup() { return true; } @Override protected String getActionText(final AnActionEvent e) { String text = ApplicationBundle.message("action.add"); if (e.getPresentation().isEnabled()) { final DomElementsGroupNode selectedNode = getDomElementsGroupNode(getTreeView(e)); if (selectedNode != null) { final Type type = selectedNode.getChildDescription().getType(); text += " " + TypePresentationService.getService().getTypePresentableName(ReflectionUtil.getRawType(type)); } } return text; } @Nullable private static DomElementsGroupNode getDomElementsGroupNode(final DomModelTreeView treeView) { SimpleNode simpleNode = treeView.getTree().getSelectedNode(); while (simpleNode != null) { if (simpleNode instanceof DomElementsGroupNode) return (DomElementsGroupNode)simpleNode; simpleNode = simpleNode.getParent(); } return null; } @Override protected AnAction createAddingAction(final AnActionEvent e, final String name, final Icon icon, final Type type, final DomCollectionChildDescription description) { final DomElement parentDomElement = getParentDomElement(e); if (parentDomElement instanceof MergedObject) { final List<DomElement> implementations = (List<DomElement>)((MergedObject)parentDomElement).getImplementations(); final DefaultActionGroup actionGroup = new DefaultActionGroup(name, true); for (DomElement implementation : implementations) { final XmlFile xmlFile = DomUtil.getFile(implementation); actionGroup.add(new MyDefaultAddAction(implementation, xmlFile.getName(), xmlFile.getIcon(0), e, type, description)); } return actionGroup; } return new MyDefaultAddAction(parentDomElement, name, icon, e, type, description); } private class MyDefaultAddAction extends DefaultAddAction { // we need this properties, don't remove it (shared dataContext assertion) private final DomElement myParent; private final DomModelTreeView myView; private final Type myType; private final DomCollectionChildDescription myDescription; public MyDefaultAddAction(final DomElement parent, final String name, final Icon icon, final AnActionEvent e, final Type type, final DomCollectionChildDescription description) { super(name, name, icon); myType = type; myDescription = description; myParent = parent; myView = getTreeView(e); } @Override protected Type getElementType() { return myType; } @Override protected DomCollectionChildDescription getDomCollectionChildDescription() { return myDescription; } @Override protected DomElement getParentDomElement() { return myParent; } @Override protected void afterAddition(@NotNull final DomElement newElement) { final DomElement copy = newElement.createStableCopy(); ApplicationManager.getApplication().invokeLater(() -> myView.setSelectedDomElement(copy)); } } }