ab66248b2ccfc62c006056dabe6651110a558878
[idea/community.git] / java / idea-ui / src / com / intellij / openapi / roots / ui / configuration / artifacts / actions / SurroundElementWithAction.java
1 /*
2  * Copyright 2000-2010 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.roots.ui.configuration.artifacts.actions;
17
18 import com.intellij.openapi.actionSystem.AnActionEvent;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorEx;
21 import com.intellij.openapi.roots.ui.configuration.artifacts.LayoutTreeComponent;
22 import com.intellij.openapi.roots.ui.configuration.artifacts.LayoutTreeSelection;
23 import com.intellij.openapi.roots.ui.configuration.artifacts.nodes.PackagingElementNode;
24 import com.intellij.openapi.ui.popup.JBPopupFactory;
25 import com.intellij.openapi.ui.popup.PopupStep;
26 import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
27 import com.intellij.packaging.elements.CompositePackagingElement;
28 import com.intellij.packaging.elements.CompositePackagingElementType;
29 import com.intellij.packaging.elements.PackagingElement;
30 import com.intellij.packaging.elements.PackagingElementFactory;
31 import com.intellij.packaging.impl.artifacts.ArtifactUtil;
32 import com.intellij.util.PathUtil;
33 import com.intellij.util.containers.ContainerUtil;
34 import org.jetbrains.annotations.NotNull;
35
36 import javax.swing.*;
37 import java.util.List;
38
39 import static com.intellij.openapi.keymap.KeymapUtil.getActiveKeymapShortcuts;
40
41 public class SurroundElementWithAction extends LayoutTreeActionBase {
42   public SurroundElementWithAction(ArtifactEditorEx artifactEditor) {
43     super("Surround With...", artifactEditor);
44     registerCustomShortcutSet(getActiveKeymapShortcuts("SurroundWith"), artifactEditor.getLayoutTreeComponent().getLayoutTree());
45   }
46
47   @Override
48   protected boolean isEnabled() {
49     return myArtifactEditor.getLayoutTreeComponent().getSelection().getCommonParentElement() != null;
50   }
51
52   @Override
53   public void actionPerformed(@NotNull AnActionEvent e) {
54     final LayoutTreeComponent treeComponent = myArtifactEditor.getLayoutTreeComponent();
55     final LayoutTreeSelection selection = treeComponent.getSelection();
56     final CompositePackagingElement<?> parent = selection.getCommonParentElement();
57     if (parent == null) return;
58     final PackagingElementNode<?> parentNode = selection.getNodes().get(0).getParentNode();
59     if (parentNode == null) return;
60
61     if (!treeComponent.checkCanModifyChildren(parent, parentNode, selection.getNodes())) {
62       return;
63     }
64
65     final CompositePackagingElementType<?>[] types = PackagingElementFactory.getInstance().getCompositeElementTypes();
66     final List<PackagingElement<?>> selected = selection.getElements();
67     if (types.length == 1) {
68       surroundWith(types[0], parent, selected, treeComponent);
69     }
70     else {
71       JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<CompositePackagingElementType>("Surround With...", types) {
72         @Override
73         public Icon getIconFor(CompositePackagingElementType aValue) {
74           return aValue.getCreateElementIcon();
75         }
76
77         @NotNull
78         @Override
79         public String getTextFor(CompositePackagingElementType value) {
80           return value.getPresentableName();
81         }
82
83         @Override
84         public PopupStep onChosen(final CompositePackagingElementType selectedValue, boolean finalChoice) {
85           return doFinalStep(() -> surroundWith(selectedValue, parent, selected, treeComponent));
86         }
87       }).showInBestPositionFor(e.getDataContext());
88     }
89   }
90
91   private void surroundWith(final CompositePackagingElementType<?> type, final CompositePackagingElement<?> parent, final List<? extends PackagingElement<?>> selected,
92                             LayoutTreeComponent treeComponent) {
93     if (myArtifactEditor.isDisposed() || selected.isEmpty()) return;
94
95     final Project project = myArtifactEditor.getContext().getProject();
96     final String elementName = ContainerUtil.getFirstItem(selected, null).createPresentation(myArtifactEditor.getContext()).getPresentableName();
97     final String baseName = PathUtil.suggestFileName(elementName);
98     final CompositePackagingElement<?> newParent = type.createComposite(parent, baseName, myArtifactEditor.getContext());
99     if (newParent != null) {
100       treeComponent.editLayout(() -> {
101         for (PackagingElement<?> element : selected) {
102           newParent.addOrFindChild(ArtifactUtil.copyWithChildren(element, project));
103         }
104         for (PackagingElement<?> element : selected) {
105           parent.removeChild(element);
106         }
107         parent.addOrFindChild(newParent);
108       });
109       treeComponent.rebuildTree();
110     }
111   }
112 }