IDEA-56280: Add New Facet

This commit is contained in:
nik
2010-10-27 10:23:18 +04:00
parent a42ef74339
commit 89a0a4b149
11 changed files with 266 additions and 117 deletions
@@ -103,14 +103,30 @@ public class ProjectFacetsConfigurator implements FacetsProvider, ModuleEditor.C
return removed;
}
public Facet createAndAddFacet(Module module, FacetType<?, ?> type, String name, final @Nullable FacetInfo underlyingFacet) {
final Facet facet = FacetManager.getInstance(module).createFacet(type, name, myInfo2Facet.get(underlyingFacet));
public Facet createAndAddFacet(Module module, FacetType<?, ?> type, final @Nullable Facet underlying) {
final Collection<? extends Facet> facets = getFacetsByType(module, type.getId());
String facetName = type.getDefaultFacetName();
int i = 2;
while (facetExists(facetName, facets)) {
facetName = type.getDefaultFacetName() + i;
i++;
}
final Facet facet = FacetManager.getInstance(module).createFacet(type, facetName, underlying);
myCreatedFacets.add(facet);
addFacetInfo(facet);
getOrCreateModifiableModel(module).addFacet(facet);
return facet;
}
private boolean facetExists(final String facetName, final Collection<? extends Facet> facets) {
for (Facet facet : facets) {
if (getFacetName(facet).equals(facetName)) {
return true;
}
}
return false;
}
public void addFacetInfo(final Facet facet) {
final FacetInfo exiting = myFacet2Info.get(facet);
if (exiting != null) {
@@ -336,6 +352,17 @@ public class ProjectFacetsConfigurator implements FacetsProvider, ModuleEditor.C
return myProjectData;
}
public String getFacetName(Facet facet) {
final ModifiableFacetModel model = myModifiableModels.get(facet.getModule());
if (model != null) {
final String newName = model.getNewName(facet);
if (newName != null) {
return newName;
}
}
return facet.getName();
}
public List<Facet> removeAllFacets(final Module module) {
List<Facet> facets = new ArrayList<Facet>();
FacetModel facetModel = getOrCreateModifiableModel(module);
@@ -351,6 +378,12 @@ public class ProjectFacetsConfigurator implements FacetsProvider, ModuleEditor.C
return facets;
}
public boolean hasFacetOfType(Module module, @Nullable Facet parent, FacetTypeId<?> typeId) {
final FacetTreeModel treeModel = getTreeModel(module);
final FacetInfo parentInfo = getFacetInfo(parent);
return treeModel.hasFacetOfType(parentInfo, typeId);
}
private class MyProjectConfigurableContext extends ProjectConfigurableContext {
private final LibrariesContainer myContainer;
@@ -16,6 +16,7 @@
package com.intellij.facet.impl.ui;
import com.intellij.facet.Facet;
import org.jetbrains.annotations.Nullable;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetInfo;
@@ -37,7 +38,7 @@ public interface FacetEditorFacade {
@Nullable
ModuleType getSelectedModuleType();
void createFacet(final FacetInfo parent, final FacetType type, final String name);
Facet createFacet(final FacetInfo parent, final FacetType type);
Collection<FacetInfo> getFacetsByType(FacetType<?,?> type);
@@ -16,17 +16,18 @@
package com.intellij.facet.impl.ui.actions;
import com.intellij.facet.FacetInfo;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeId;
import com.intellij.facet.*;
import com.intellij.facet.impl.ui.FacetEditorFacade;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import java.util.Collection;
import java.util.Arrays;
import java.util.Comparator;
/**
* @author nik
@@ -34,43 +35,31 @@ import java.util.Collection;
public class AddFacetAction extends AnAction implements DumbAware {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.ui.actions.AddFacetAction");
private final FacetEditorFacade myEditor;
private final Project myProject;
private final FacetType myType;
public AddFacetAction(final FacetEditorFacade editor, final FacetType type) {
public AddFacetAction(final FacetEditorFacade editor, Project project, final FacetType type) {
super(type.getPresentableName(), null, type.getIcon());
myEditor = editor;
myProject = project;
myType = type;
}
public void actionPerformed(AnActionEvent e) {
FacetInfo parent = myEditor.getSelectedFacetInfo();
final Collection<FacetInfo> facetInfos = myEditor.getFacetsByType(myType);
String facetName = myType.getDefaultFacetName();
int i = 2;
while (facetExists(facetName, facetInfos)) {
facetName = myType.getPresentableName() + i;
i++;
}
final FacetTypeId<?> underlyingFacetType = myType.getUnderlyingFacetType();
Facet facet;
if (parent == null && underlyingFacetType == null || parent != null && parent.getFacetType().getId() == underlyingFacetType) {
myEditor.createFacet(parent, myType, facetName);
facet = myEditor.createFacet(parent, myType);
}
else {
LOG.assertTrue(parent != null);
final FacetInfo grandParent = myEditor.getParent(parent);
LOG.assertTrue(grandParent == null && underlyingFacetType == null ||
grandParent != null && grandParent.getFacetType().getId() == underlyingFacetType);
myEditor.createFacet(grandParent, myType, facetName);
facet = myEditor.createFacet(grandParent, myType);
}
}
private static boolean facetExists(final String facetName, final Collection<FacetInfo> facetInfos) {
for (FacetInfo facetInfo : facetInfos) {
if (facetInfo.getName().equals(facetName)) {
return true;
}
}
return false;
ProjectStructureConfigurable.getInstance(myProject).select(facet, true);
}
public void update(AnActionEvent e) {
@@ -104,4 +93,19 @@ public class AddFacetAction extends AnAction implements DumbAware {
private static boolean canAddFacet(final FacetInfo selectedFacet, final FacetType<?, ?> type, final FacetEditorFacade editor) {
return !(type.isOnlyOneFacetAllowed() && editor.nodeHasFacetOfType(selectedFacet, type.getId()));
}
public static AnAction[] createAddFacetActions(FacetEditorFacade editor, Project project) {
final FacetType[] types = FacetTypeRegistry.getInstance().getFacetTypes();
Arrays.sort(types, new Comparator<FacetType>() {
public int compare(final FacetType o1, final FacetType o2) {
return o1.getPresentableName().compareTo(o2.getPresentableName());
}
});
AnAction[] actions = new AnAction[types.length];
for (int i = 0; i < types.length; i++) {
actions[i] = new AddFacetAction(editor, project, types[i]);
}
return actions;
}
}
@@ -1,80 +0,0 @@
/*
* Copyright 2000-2009 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.facet.impl.ui.actions;
import com.intellij.facet.impl.ui.FacetEditorFacade;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAware;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Comparator;
/**
* @author nik
*/
public class AddFacetActionGroup extends ActionGroup implements DumbAware {
private final boolean myFromPopup;
private final FacetEditorFacade myEditor;
private AnAction[] myCachedChildren;
public AddFacetActionGroup(final String groupName, final boolean fromPopup, final FacetEditorFacade editor) {
super(groupName, true);
myFromPopup = fromPopup;
myEditor = editor;
}
public AnAction[] getChildren(@Nullable AnActionEvent e) {
if (myCachedChildren == null) {
final FacetType[] types = FacetTypeRegistry.getInstance().getFacetTypes();
Arrays.sort(types, new Comparator<FacetType>() {
public int compare(final FacetType o1, final FacetType o2) {
return o1.getPresentableName().compareTo(o2.getPresentableName());
}
});
myCachedChildren = new AnAction[types.length];
for (int i = 0; i < types.length; i++) {
myCachedChildren[i] = new AddFacetAction(myEditor, types[i]);
}
}
return myCachedChildren;
}
public void update(AnActionEvent e) {
final boolean visible = isVisible();
if (myFromPopup) {
e.getPresentation().setVisible(visible);
}
else {
e.getPresentation().setEnabled(visible);
}
}
private boolean isVisible() {
for (FacetType type : FacetTypeRegistry.getInstance().getFacetTypes()) {
if (AddFacetAction.isVisible(myEditor, type)) {
return true;
}
}
return false;
}
}
@@ -40,6 +40,10 @@ public class ChooseModulesDialog extends ChooseElementsDialog<Module> {
super(project, items, title, description, true);
}
public void setSingleSelectionMode() {
myChooser.setSingleSelectionMode();
}
protected Icon getItemIcon(final Module item) {
return item.getModuleType().getNodeIcon(false);
}
@@ -0,0 +1,164 @@
/*
* 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.projectRoot;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeId;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.facet.impl.ProjectFacetsConfigurator;
import com.intellij.ide.util.ChooseElementsDialog;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.ChooseModulesDialog;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.util.Icons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* @author nik
*/
class AddFacetOfTypeAction extends DumbAwareAction {
private FacetStructureConfigurable myFacetStructureConfigurable;
AddFacetOfTypeAction(FacetStructureConfigurable facetStructureConfigurable) {
super("New Facet", null, Icons.ADD_ICON);
this.myFacetStructureConfigurable = facetStructureConfigurable;
}
@Override
public void actionPerformed(AnActionEvent e) {
final FacetType type = getSelectedType();
if (type == null) return;
final FacetTypeId underlyingFacetType = type.getUnderlyingFacetType();
if (underlyingFacetType == null) {
addFacetToModule(type);
}
else {
addSubFacet(type, underlyingFacetType);
}
}
private void addSubFacet(FacetType type, FacetTypeId<?> underlyingType) {
final StructureConfigurableContext context = myFacetStructureConfigurable.myContext;
final ProjectFacetsConfigurator facetsConfigurator = context.getModulesConfigurator().getFacetsConfigurator();
List<Facet> suitableParents = new ArrayList<Facet>();
for (Module module : context.getModules()) {
if (type.isSuitableModuleType(module.getModuleType())) {
suitableParents.addAll(facetsConfigurator.getFacetsByType(module, underlyingType));
}
}
final Iterator<Facet> iterator = suitableParents.iterator();
while (iterator.hasNext()) {
Facet parent = iterator.next();
if (type.isOnlyOneFacetAllowed() && facetsConfigurator.hasFacetOfType(parent.getModule(), parent, type.getId())) {
iterator.remove();
}
}
final Project project = context.getProject();
if (suitableParents.isEmpty()) {
final String parentType = FacetTypeRegistry.getInstance().findFacetType(underlyingType).getPresentableName();
Messages.showErrorDialog(project, "No suitable parent " + parentType + " facets found", "Cannot Create " + type.getPresentableName() + " Facet");
return;
}
ChooseParentFacetDialog dialog = new ChooseParentFacetDialog(project, suitableParents, "Select Parent Facet", null);
dialog.show();
final List<Facet> chosen = dialog.getChosenElements();
if (!dialog.isOK() || chosen.size() != 1) return;
final Facet parent = chosen.get(0);
final Facet facet =
ModuleStructureConfigurable.getInstance(project).getFacetEditorFacade().createAndAddFacet(type, parent.getModule(), parent);
ProjectStructureConfigurable.getInstance(project).select(facet, true);
}
private void addFacetToModule(@NotNull FacetType type) {
final StructureConfigurableContext context = myFacetStructureConfigurable.myContext;
final ProjectFacetsConfigurator facetsConfigurator = context.getModulesConfigurator().getFacetsConfigurator();
List<Module> suitableModules = new ArrayList<Module>(Arrays.asList(context.getModules()));
final Iterator<Module> iterator = suitableModules.iterator();
while (iterator.hasNext()) {
Module module = iterator.next();
if (!type.isSuitableModuleType(module.getModuleType()) || (type.isOnlyOneFacetAllowed() && facetsConfigurator.hasFacetOfType(module, null, type.getId()))) {
iterator.remove();
}
}
final Project project = context.getProject();
if (suitableModules.isEmpty()) {
Messages.showErrorDialog(project, "No suitable modules for " + type.getPresentableName() + " facet found.", "Cannot Create Facet");
return;
}
final ChooseModulesDialog dialog = new ChooseModulesDialog(project, suitableModules, "Choose Module",
type.getPresentableName() + " facet will be added to selected module");
dialog.setSingleSelectionMode();
dialog.show();
final List<Module> elements = dialog.getChosenElements();
if (!dialog.isOK() || elements.size() != 1) return;
final Module module = elements.get(0);
final Facet facet = ModuleStructureConfigurable.getInstance(project).getFacetEditorFacade().createAndAddFacet(type, module, null);
ProjectStructureConfigurable.getInstance(project).select(facet, true);
}
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(myFacetStructureConfigurable.myContext.getModules().length > 0 && getSelectedType() != null);
}
@Nullable
private FacetType getSelectedType() {
final NamedConfigurable configurable = myFacetStructureConfigurable.getSelectedConfugurable();
if (configurable instanceof FacetTypeConfigurable) {
return ((FacetTypeConfigurable)configurable).getFacetType();
}
else if (configurable instanceof FacetConfigurable) {
return ((FacetConfigurable)configurable).getEditableObject().getType();
}
return null;
}
private static class ChooseParentFacetDialog extends ChooseElementsDialog<Facet> {
private ChooseParentFacetDialog(Project project, List<? extends Facet> items, String title, String description) {
super(project, items, title, description);
myChooser.setSingleSelectionMode();
}
@Override
protected String getItemText(Facet item) {
return item.getName() + " (module " + item.getModule().getName() + ")";
}
@Override
protected Icon getItemIcon(Facet item) {
return item.getType().getIcon();
}
}
}
@@ -59,6 +59,12 @@ public class FacetEditorFacadeImpl implements FacetEditorFacade {
return facetsExist;
}
private void addFacetNode(Facet facet) {
addFacetNode(facet, myStructureConfigurable.findModuleNode(facet.getModule()));
final FacetStructureConfigurable facetStructureConfigurable = FacetStructureConfigurable.getInstance(myStructureConfigurable.getProject());
facetStructureConfigurable.addFacetNode(facetStructureConfigurable.findFacetTypeNode(facet.getType()), facet, this);
}
private MasterDetailsComponent.MyNode addFacetNode(final Facet facet, final MasterDetailsComponent.MyNode moduleNode) {
final MasterDetailsComponent.MyNode existing = findFacetNode(facet, moduleNode);
if (existing != null) return existing;
@@ -113,12 +119,14 @@ public class FacetEditorFacadeImpl implements FacetEditorFacade {
return facetTreeModel.hasFacetOfType(facet, typeId);
}
public void createFacet(final FacetInfo parent, FacetType type, final String name) {
Module module = getSelectedModule();
public Facet createFacet(final FacetInfo parent, FacetType type) {
return createAndAddFacet(type, getSelectedModule(), getFacetConfigurator().getFacet(parent));
}
final Facet facet = getFacetConfigurator().createAndAddFacet(module, type, name, parent);
final MasterDetailsComponent.MyNode node = addFacetNode(facet, myStructureConfigurable.findModuleNode(module));
myStructureConfigurable.selectNodeInTree(node);
public Facet createAndAddFacet(FacetType type, Module module, final Facet underlying) {
final Facet facet = getFacetConfigurator().createAndAddFacet(module, type, underlying);
addFacetNode(facet);
return facet;
}
public Collection<FacetInfo> getFacetsByType(final FacetType<?,?> type) {
@@ -81,13 +81,21 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
Collection<? extends Facet> facets = FacetManager.getInstance(module).getFacetsByType(facetType.getId());
for (Facet facet : facets) {
FacetEditorFacadeImpl editorFacade = ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade();
FacetConfigurable facetConfigurable = editorFacade.getOrCreateConfigurable(facet);
addNode(new FacetConfigurableNode(facetConfigurable), facetTypeNode);
addFacetNode(facetTypeNode, facet, editorFacade);
}
}
}
}
public MyNode findFacetTypeNode(FacetType facetType) {
return findNodeByObject(myRoot, facetType);
}
public void addFacetNode(MyNode facetTypeNode, Facet facet, FacetEditorFacadeImpl editorFacade) {
FacetConfigurable facetConfigurable = editorFacade.getOrCreateConfigurable(facet);
addNode(new FacetConfigurableNode(facetConfigurable), facetTypeNode);
}
@Nullable
public FacetTypeEditor getFacetTypeEditor(@NotNull FacetType<?, ?> facetType) {
return myFacetTypeEditors.get(facetType);
@@ -144,6 +152,7 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
@NotNull
protected ArrayList<AnAction> createActions(final boolean fromPopup) {
ArrayList<AnAction> actions = new ArrayList<AnAction>();
actions.add(new AddFacetOfTypeAction(this));
if (fromPopup) {
actions.add(new MyNavigateAction());
}
@@ -58,6 +58,10 @@ public class FacetTypeConfigurable extends NamedConfigurable<FacetType> {
return myFacetType.getIcon();
}
public FacetType getFacetType() {
return myFacetType;
}
public String getHelpTopic() {
final FacetTypeEditor editor = myFacetStructureConfigurable.getFacetTypeEditor(myFacetType);
return editor != null ? editor.getHelpTopic() : null;
@@ -19,7 +19,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot;
import com.intellij.CommonBundle;
import com.intellij.facet.Facet;
import com.intellij.facet.impl.ProjectFacetsConfigurator;
import com.intellij.facet.impl.ui.actions.AddFacetActionGroup;
import com.intellij.facet.impl.ui.actions.AddFacetAction;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.ide.projectView.impl.ModuleGroup;
@@ -646,8 +646,6 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
}
protected AbstractAddGroup createAddAction() {
final AddFacetActionGroup addFacetGroup = new AddFacetActionGroup("", true, myFacetEditorFacade);
return new AbstractAddGroup(ProjectBundle.message("add.new.header.text")) {
@NotNull
public AnAction[] getChildren(@Nullable final AnActionEvent e) {
@@ -656,7 +654,7 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
ArrayList<AnAction> result = new ArrayList<AnAction>();
result.add(module);
final AnAction[] facets = addFacetGroup.getChildren(e);
final AnAction[] facets = AddFacetAction.createAddFacetActions(myFacetEditorFacade, myProject);
if (facets.length > 0) {
result.add(new Separator(ProjectBundle.message("add.group.facet.separator")));
ContainerUtil.addAll(result, facets);
@@ -134,6 +134,10 @@ public class ElementsChooser<T> extends JPanel {
setElements(elements, marked);
}
public void setSingleSelectionMode() {
myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
public void refresh() {
myTableModel.fireTableDataChanged();
}