From 5d539e6b5ef9e6419652f1567f986c399afbc53e Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 2 Feb 2010 13:15:19 +0300 Subject: [PATCH] IDEA-27190: Artifacts: Add context action to create .jar archieve from module output & "Extract artifact" action improved --- .../impl/elements/ArchiveElementType.java | 6 +- .../impl/elements/DirectoryElementType.java | 5 +- .../impl/elements/PackagingElementFactoryImpl.java | 4 +- .../elements/CompositePackagingElementType.java | 4 +- .../com/intellij/packaging/ui/ArtifactEditor.java | 2 + .../artifacts/ArtifactConfigurable.java | 12 +- .../artifacts/ArtifactEditorImpl.java | 7 ++ .../artifacts/ArtifactTypeCellRenderer.java | 35 ++++++ .../artifacts/actions/ExtractArtifactAction.java | 48 ++++---- .../artifacts/actions/ExtractArtifactDialog.form | 50 +++++++++ .../artifacts/actions/ExtractArtifactDialog.java | 88 +++++++++++++++ .../actions/SurroundElementWithAction.java | 124 +++++++++++++++++++++ .../src/messages/ProjectBundle.properties | 4 +- 13 files changed, 347 insertions(+), 42 deletions(-) create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactTypeCellRenderer.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.form create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/SurroundElementWithAction.java diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java index d5abb844fe..77c78ee99e 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java @@ -21,12 +21,12 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.elements.CompositePackagingElementType; -import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.impl.ui.properties.ArchiveElementPropertiesPanel; import com.intellij.packaging.ui.ArtifactEditorContext; import com.intellij.packaging.ui.PackagingElementPropertiesPanel; import com.intellij.util.Icons; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -59,8 +59,8 @@ class ArchiveElementType extends CompositePackagingElementType createComposite(@NotNull ArtifactEditorContext context, CompositePackagingElement parent) { - final String initialValue = PackagingElementFactoryImpl.suggestFileName(parent, "archive", ".jar"); + public CompositePackagingElement createComposite(CompositePackagingElement parent, @Nullable String baseName, @NotNull ArtifactEditorContext context) { + final String initialValue = PackagingElementFactoryImpl.suggestFileName(parent, baseName != null ? baseName : "archive", ".jar"); final String path = Messages.showInputDialog(context.getProject(), "Enter archive name: ", "New Archive", null, initialValue, new FilePathValidator()); if (path == null) return null; return PackagingElementFactoryImpl.createDirectoryOrArchiveWithParents(path, true); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryElementType.java index d3b9a5dd46..b133880138 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryElementType.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryElementType.java @@ -21,7 +21,6 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.IconLoader; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.elements.CompositePackagingElementType; -import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.impl.artifacts.ArtifactUtil; import com.intellij.packaging.impl.ui.properties.DirectoryElementPropertiesPanel; import com.intellij.packaging.ui.ArtifactEditorContext; @@ -59,8 +58,8 @@ class DirectoryElementType extends CompositePackagingElementType createComposite(@NotNull ArtifactEditorContext context, CompositePackagingElement parent) { - final String initialValue = PackagingElementFactoryImpl.suggestFileName(parent, "folder", ""); + public CompositePackagingElement createComposite(CompositePackagingElement parent, String baseName, @NotNull ArtifactEditorContext context) { + final String initialValue = PackagingElementFactoryImpl.suggestFileName(parent, baseName != null ? baseName : "folder", ""); String path = Messages.showInputDialog(context.getProject(), "Enter directory name: ", "New Directory", null, initialValue, new FilePathValidator()); if (path == null) return null; return PackagingElementFactoryImpl.createDirectoryOrArchiveWithParents(path, false); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java index 643853800c..1d527a257d 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java @@ -291,12 +291,12 @@ public class PackagingElementFactoryImpl extends PackagingElementFactory { return Collections.singletonList(root); } - public static PackagingElement createDirectoryOrArchiveWithParents(@NotNull String path, final boolean archive) { + public static CompositePackagingElement createDirectoryOrArchiveWithParents(@NotNull String path, final boolean archive) { path = FileUtil.toSystemIndependentName(path); final String parentPath = PathUtil.getParentPath(path); final String fileName = PathUtil.getFileName(path); final PackagingElement element = archive ? new ArchivePackagingElement(fileName) : new DirectoryPackagingElement(fileName); - return getInstance().createParentDirectories(parentPath, element); + return (CompositePackagingElement)getInstance().createParentDirectories(parentPath, element); } private static class ArtifactRootElementType extends PackagingElementType> { diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java index 66025980b4..92af59db1a 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java +++ b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java @@ -39,11 +39,11 @@ public abstract class CompositePackagingElementType createComposite(@NotNull ArtifactEditorContext context, CompositePackagingElement parent); + public abstract CompositePackagingElement createComposite(CompositePackagingElement parent, @Nullable String baseName, @NotNull ArtifactEditorContext context); @NotNull public List> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact, @NotNull CompositePackagingElement parent) { - final PackagingElement composite = createComposite(context, parent); + final PackagingElement composite = createComposite(parent, null, context); return composite != null ? Collections.singletonList(composite) : Collections.emptyList(); } } diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java index 4609d97c51..144bda2e6e 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java +++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java @@ -33,4 +33,6 @@ public interface ArtifactEditor { void putModuleIntoDefaultLocation(@NotNull Module module); void addToClasspath(CompositePackagingElement element, List classpath); + + boolean isDisposed(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java index 39aa60543a..255e9bfefd 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java @@ -108,16 +108,7 @@ public class ArtifactConfigurable extends ProjectStructureElementConfigurable selectedElements = selection.getElements(); - final String name = Messages.showInputDialog(myArtifactEditor.getMainComponent(), ProjectBundle.message("label.text.specify.artifact.name"), - ProjectBundle.message("dialog.title.extract.artifact"), null); - if (name != null) { - final Project project = myArtifactEditor.getContext().getProject(); - //todo[nik] select type? - final ModifiableArtifact artifact = myArtifactEditor.getContext().getOrCreateModifiableArtifactModel().addArtifact(name, PlainArtifactType.getInstance()); - treeComponent.editLayout(new Runnable() { - public void run() { - for (PackagingElement element : selectedElements) { - artifact.getRootElement().addOrFindChild(ArtifactUtil.copyWithChildren(element, project)); - } - for (PackagingElement element : selectedElements) { - parent.removeChild(element); - } - parent.addOrFindChild(new ArtifactPackagingElement(project, ArtifactPointerManager.getInstance(project).createPointer(artifact, myArtifactEditor.getContext().getArtifactModel()))); - } - }); - treeComponent.rebuildTree(); + String initialName = "artifact"; + if (selectedElements.size() == 1) { + initialName = PathUtil.suggestFileName(ContainerUtil.getFirstItem(selectedElements, null).createPresentation(myArtifactEditor.getContext()).getPresentableName()); + } + final ExtractArtifactDialog dialog = new ExtractArtifactDialog(myArtifactEditor.getContext(), treeComponent, initialName); + dialog.show(); + if (!dialog.isOK()) { + return; } + + final Project project = myArtifactEditor.getContext().getProject(); + final ModifiableArtifactModel model = myArtifactEditor.getContext().getOrCreateModifiableArtifactModel(); + final ModifiableArtifact artifact = model.addArtifact(dialog.getArtifactName(), dialog.getArtifactType()); + treeComponent.editLayout(new Runnable() { + public void run() { + for (PackagingElement element : selectedElements) { + artifact.getRootElement().addOrFindChild(ArtifactUtil.copyWithChildren(element, project)); + } + for (PackagingElement element : selectedElements) { + parent.removeChild(element); + } + parent.addOrFindChild(new ArtifactPackagingElement(project, ArtifactPointerManager.getInstance(project).createPointer(artifact, myArtifactEditor.getContext().getArtifactModel()))); + } + }); + treeComponent.rebuildTree(); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.form b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.form new file mode 100644 index 0000000000..d7499bfcaf --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.form @@ -0,0 +1,50 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.java new file mode 100644 index 0000000000..11752e635b --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ExtractArtifactDialog.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2010 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.openapi.roots.ui.configuration.artifacts.actions; + +import com.intellij.CommonBundle; +import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactTypeCellRenderer; +import com.intellij.openapi.roots.ui.configuration.artifacts.LayoutTreeComponent; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.packaging.artifacts.ArtifactType; +import com.intellij.packaging.impl.artifacts.PlainArtifactType; +import com.intellij.packaging.ui.ArtifactEditorContext; +import com.intellij.ui.DocumentAdapter; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; + +/** + * @author nik + */ +public class ExtractArtifactDialog extends DialogWrapper { + private JPanel myMainPanel; + private JTextField myNameField; + private JComboBox myTypeBox; + private final ArtifactEditorContext myContext; + + public ExtractArtifactDialog(ArtifactEditorContext context, LayoutTreeComponent treeComponent, String initialName) { + super(treeComponent.getLayoutTree(), true); + myContext = context; + setTitle(ProjectBundle.message("dialog.title.extract.artifact")); + for (ArtifactType type : ArtifactType.getAllTypes()) { + myTypeBox.addItem(type); + } + myTypeBox.setSelectedItem(PlainArtifactType.getInstance()); + myTypeBox.setRenderer(new ArtifactTypeCellRenderer()); + myNameField.getDocument().addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + setOKActionEnabled(!StringUtil.isEmptyOrSpaces(getArtifactName())); + } + }); + myNameField.setText(initialName); + init(); + } + + @Override + protected void doOKAction() { + final String artifactName = getArtifactName(); + if (myContext.getArtifactModel().findArtifact(artifactName) != null) { + Messages.showErrorDialog(myContext.getProject(), "Artifact '" + artifactName + "' already exists!", CommonBundle.getErrorTitle()); + return; + } + super.doOKAction(); + } + + @Override + protected JComponent createCenterPanel() { + return myMainPanel; + } + + public String getArtifactName() { + return myNameField.getText(); + } + + public ArtifactType getArtifactType() { + return (ArtifactType)myTypeBox.getSelectedItem(); + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myNameField; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/SurroundElementWithAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/SurroundElementWithAction.java new file mode 100644 index 0000000000..686f241e9c --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/SurroundElementWithAction.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2010 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.openapi.roots.ui.configuration.artifacts.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorEx; +import com.intellij.openapi.roots.ui.configuration.artifacts.LayoutTreeComponent; +import com.intellij.openapi.roots.ui.configuration.artifacts.LayoutTreeSelection; +import com.intellij.openapi.roots.ui.configuration.artifacts.nodes.PackagingElementNode; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.elements.CompositePackagingElementType; +import com.intellij.packaging.elements.PackagingElement; +import com.intellij.packaging.elements.PackagingElementFactory; +import com.intellij.packaging.impl.artifacts.ArtifactUtil; +import com.intellij.util.PathUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.List; + +/** + * @author nik + */ +public class SurroundElementWithAction extends LayoutTreeActionBase { + public SurroundElementWithAction(ArtifactEditorEx artifactEditor) { + super("Surround With...", artifactEditor); + final CustomShortcutSet shortcutSet = new CustomShortcutSet(KeymapManager.getInstance().getActiveKeymap().getShortcuts("SurroundWith")); + registerCustomShortcutSet(shortcutSet, artifactEditor.getLayoutTreeComponent().getLayoutTree()); + } + + @Override + protected boolean isEnabled() { + return myArtifactEditor.getLayoutTreeComponent().getSelection().getCommonParentElement() != null; + } + + @Override + public void actionPerformed(AnActionEvent e) { + final LayoutTreeComponent treeComponent = myArtifactEditor.getLayoutTreeComponent(); + final LayoutTreeSelection selection = treeComponent.getSelection(); + final CompositePackagingElement parent = selection.getCommonParentElement(); + if (parent == null) return; + final PackagingElementNode parentNode = selection.getNodes().get(0).getParentNode(); + if (parentNode == null) return; + + if (!treeComponent.checkCanModifyChildren(parent, parentNode, selection.getNodes())) { + return; + } + + final CompositePackagingElementType[] types = PackagingElementFactory.getInstance().getCompositeElementTypes(); + final List> selected = selection.getElements(); + if (types.length == 1) { + surroundWith(types[0], parent, selected, treeComponent); + } + else { + JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep("Surround With...", types) { + @Override + public Icon getIconFor(CompositePackagingElementType aValue) { + return aValue.getCreateElementIcon(); + } + + @NotNull + @Override + public String getTextFor(CompositePackagingElementType value) { + return value.getPresentableName(); + } + + @Override + public PopupStep onChosen(final CompositePackagingElementType selectedValue, boolean finalChoice) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + surroundWith(selectedValue, parent, selected, treeComponent); + } + }); + return FINAL_CHOICE; + } + }).showInBestPositionFor(e.getDataContext()); + } + } + + private void surroundWith(final CompositePackagingElementType type, final CompositePackagingElement parent, final List> selected, + LayoutTreeComponent treeComponent) { + if (myArtifactEditor.isDisposed() || selected.isEmpty()) return; + + final Project project = myArtifactEditor.getContext().getProject(); + final String elementName = ContainerUtil.getFirstItem(selected, null).createPresentation(myArtifactEditor.getContext()).getPresentableName(); + final String baseName = PathUtil.suggestFileName(elementName); + final CompositePackagingElement newParent = type.createComposite(parent, baseName, myArtifactEditor.getContext()); + if (newParent != null) { + treeComponent.editLayout(new Runnable() { + public void run() { + for (PackagingElement element : selected) { + newParent.addOrFindChild(ArtifactUtil.copyWithChildren(element, project)); + } + for (PackagingElement element : selected) { + parent.removeChild(element); + } + parent.addOrFindChild(newParent); + } + }); + treeComponent.rebuildTree(); + } + } +} diff --git a/platform/platform-resources-en/src/messages/ProjectBundle.properties b/platform/platform-resources-en/src/messages/ProjectBundle.properties index 0fdd01a199..374e51fe6e 100644 --- a/platform/platform-resources-en/src/messages/ProjectBundle.properties +++ b/platform/platform-resources-en/src/messages/ProjectBundle.properties @@ -429,8 +429,8 @@ checkbox.text.build.on.make=&Build on make action.name.remove.packaging.element=Remove action.description.remove.packaging.elements=Remove Selected Elements artifacts.create.action=Create {0} -action.name.extract.artifact=Extract Artifact -label.text.specify.artifact.name=Specify artifact name: +action.name.extract.artifact=Extract Artifact... +label.text.specify.artifact.name=Specify artifact &name: dialog.title.extract.artifact=Extract Artifact action.name.inline.artifact=Inline Artifact action.name.rename.packaging.element=Rename -- 2.11.4.GIT