diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java index a6aa3092a96f..d8a23887bf60 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddItemPopupAction.java @@ -15,6 +15,9 @@ */ package com.intellij.openapi.roots.ui.configuration.classpath; +import com.intellij.openapi.ui.popup.PopupStep; +import org.jetbrains.annotations.Nullable; + import javax.swing.*; /** @@ -32,6 +35,15 @@ abstract class AddItemPopupAction extends ChooseAndAddAction myIndex = index; } + public boolean hasSubStep() { + return false; + } + + @Nullable + public PopupStep createSubStep() { + return null; + } + public String getTitle() { return myTitle; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddLibraryAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddLibraryAction.java index c392afa1df99..09711c05fd54 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddLibraryAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddLibraryAction.java @@ -23,8 +23,10 @@ import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.util.Icons; import com.intellij.util.ui.classpath.ChooseLibrariesFromTablesDialog; import org.jetbrains.annotations.Nullable; @@ -36,13 +38,21 @@ import java.util.List; */ class AddLibraryAction extends AddItemPopupAction { private StructureConfigurableContext myContext; - private AddNewLibraryItemAction myNewLibraryAction; public AddLibraryAction(ClasspathPanel classpathPanel, final int index, final String title, final StructureConfigurableContext context) { super(classpathPanel, index, title, Icons.LIBRARY_ICON); myContext = context; - myNewLibraryAction = new AddNewLibraryItemAction(classpathPanel, context); + } + + @Override + public boolean hasSubStep() { + return !hasLibraries() && AddNewLibraryItemAction.hasSuitableTypes(myClasspathPanel); + } + + @Override + public PopupStep createSubStep() { + return AddNewLibraryItemAction.createChooseTypeStep(myClasspathPanel, myContext, null); } @Override @@ -51,16 +61,19 @@ class AddLibraryAction extends AddItemPopupAction { super.run(); } else { - myNewLibraryAction.run(); + new AddNewLibraryItemAction(myClasspathPanel, myContext, null).run(); } } private boolean hasLibraries() { final Predicate condition = LibraryEditingUtil.getNotAddedLibrariesCondition(myClasspathPanel.getRootModel()); for (LibraryTable table : ChooseLibrariesFromTablesDialog.getLibraryTables(myClasspathPanel.getProject(), true)) { - for (Library library : table.getLibraries()) { - if (condition.apply(library)) { - return true; + final LibrariesModifiableModel model = myContext.myLevel2Providers.get(table.getTableLevel()); + if (model != null) { + for (Library library : model.getLibraries()) { + if (condition.apply(library)) { + return true; + } } } } @@ -101,8 +114,8 @@ class AddLibraryAction extends AddItemPopupAction { public void doChoose() { final Predicate condition = LibraryEditingUtil.getNotAddedLibrariesCondition(myClasspathPanel.getRootModel()); - ProjectStructureChooseLibrariesDialog dialog = new ProjectStructureChooseLibrariesDialog(myClasspathPanel.getComponent(), myClasspathPanel.getProject(), myContext, - condition, myNewLibraryAction); + ProjectStructureChooseLibrariesDialog dialog = new ProjectStructureChooseLibrariesDialog(myClasspathPanel, myContext, + condition); dialog.show(); mySelectedLibraries = dialog.getSelectedLibraries(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddNewLibraryItemAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddNewLibraryItemAction.java index 0242fe83344c..ee73701ab151 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddNewLibraryItemAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/AddNewLibraryItemAction.java @@ -15,21 +15,37 @@ */ package com.intellij.openapi.roots.ui.configuration.classpath; +import com.intellij.ide.IdeBundle; +import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryType; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListPopup; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.util.Icons; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; /** * @author nik */ class AddNewLibraryItemAction extends ChooseAndAddAction { private final StructureConfigurableContext myContext; + private LibraryType myLibraryType; public AddNewLibraryItemAction(final ClasspathPanel classpathPanel, - StructureConfigurableContext context) { + StructureConfigurableContext context, LibraryType libraryType) { super(classpathPanel); myContext = context; + myLibraryType = libraryType; } protected ClasspathTableItem createTableItem(final Library item) { @@ -46,6 +62,64 @@ class AddNewLibraryItemAction extends ChooseAndAddAction { } protected ClasspathElementChooser createChooser() { - return new NewLibraryChooser(myClasspathPanel.getProject(), myClasspathPanel.getRootModel(), myContext, myClasspathPanel.getComponent()); + return new NewLibraryChooser(myClasspathPanel.getProject(), myClasspathPanel.getRootModel(), myLibraryType, myContext, myClasspathPanel.getComponent()); + } + + public static void chooseTypeAndExecute(final ClasspathPanel classpathPanel, + final StructureConfigurableContext context, + final DialogWrapper parentDialog, + JButton contextButton) { + if (hasSuitableTypes(classpathPanel)) { + final ListPopup popup = JBPopupFactory.getInstance().createListPopup(createChooseTypeStep(classpathPanel, context, parentDialog)); + popup.showUnderneathOf(contextButton); + } + else { + if (parentDialog != null) parentDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + new AddNewLibraryItemAction(classpathPanel, context, null).execute(); + } + } + + public static BaseListPopupStep createChooseTypeStep(final ClasspathPanel classpathPanel, + final StructureConfigurableContext context, + final DialogWrapper parentDialog) { + return new BaseListPopupStep("Select Library Type", getSuitableTypes(classpathPanel)) { + @NotNull + @Override + public String getTextFor(LibraryType value) { + return value != null ? value.getCreateActionName() : IdeBundle.message("create.default.library.type.action.name"); + } + + @Override + public Icon getIconFor(LibraryType aValue) { + return aValue != null ? aValue.getIcon() : Icons.LIBRARY_ICON; + } + + @Override + public PopupStep onChosen(final LibraryType selectedValue, boolean finalChoice) { + return doFinalStep(new Runnable() { + @Override + public void run() { + if (parentDialog != null) parentDialog.close(DialogWrapper.CANCEL_EXIT_CODE); + new AddNewLibraryItemAction(classpathPanel, context, selectedValue).execute(); + } + }); + } + }; + } + + public static boolean hasSuitableTypes(ClasspathPanel panel) { + return getSuitableTypes(panel).size() > 1; + } + + private static List getSuitableTypes(ClasspathPanel classpathPanel) { + List suitableTypes = new ArrayList(); + suitableTypes.add(null); + final ModuleType moduleType = classpathPanel.getRootModel().getModule().getModuleType(); + for (LibraryType libraryType : LibraryType.EP_NAME.getExtensions()) { + if (libraryType.isSuitableForModuleType(moduleType)) { + suitableTypes.add(libraryType); + } + } + return suitableTypes; } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java index 623523a41471..fe9bb3a0fea8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java @@ -312,10 +312,18 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { return aValue.getIcon(); } + @Override + public boolean hasSubstep(AddItemPopupAction selectedValue) { + return selectedValue.hasSubStep(); + } + public boolean isMnemonicsNavigationEnabled() { return true; } public PopupStep onChosen(final AddItemPopupAction selectedValue, final boolean finalChoice) { + if (selectedValue.hasSubStep()) { + return selectedValue.createSubStep(); + } return doFinalStep(new Runnable() { public void run() { selectedValue.execute(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/NewLibraryChooser.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/NewLibraryChooser.java index b892182b9bd9..9f8e6e30069f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/NewLibraryChooser.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/NewLibraryChooser.java @@ -23,6 +23,7 @@ import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.roots.libraries.LibraryType; import com.intellij.openapi.roots.ui.configuration.libraryEditor.CreateNewLibraryDialog; import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; @@ -42,11 +43,13 @@ class NewLibraryChooser implements ClasspathElementChooser { private StructureConfigurableContext myContext; private final JComponent myParentComponent; private final Project myProject; + private LibraryType myLibraryType; public NewLibraryChooser(final Project project, - final ModifiableRootModel rootModel, - StructureConfigurableContext context, final JComponent parentComponent) { + final ModifiableRootModel rootModel, + LibraryType libraryType, StructureConfigurableContext context, final JComponent parentComponent) { myRootModel = rootModel; + myLibraryType = libraryType; myContext = context; myParentComponent = parentComponent; myProject = project; @@ -57,11 +60,20 @@ class NewLibraryChooser implements ClasspathElementChooser { } public void doChoose() { + final NewLibraryEditor libraryEditor; + if (myLibraryType == null) { + libraryEditor = new NewLibraryEditor(); + } + else { + libraryEditor = new NewLibraryEditor(myLibraryType, myLibraryType.createDefaultProperties()); + } + final LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance(); List tables = Arrays.asList(myRootModel.getModuleLibraryTable(), registrar.getLibraryTable(myProject), registrar.getLibraryTable()); - CreateNewLibraryDialog dialog = new CreateNewLibraryDialog(myParentComponent, myContext, new NewLibraryEditor(), tables, 1); + + CreateNewLibraryDialog dialog = new CreateNewLibraryDialog(myParentComponent, myContext, libraryEditor, tables, 1); final Module contextModule = DataKeys.MODULE_CONTEXT.getData(DataManager.getInstance().getDataContext(myParentComponent)); dialog.setContextModule(contextModule); dialog.show(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java index 33d4d136749b..44485486b5c5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java @@ -27,7 +27,6 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigur import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.ui.classpath.ChooseLibrariesFromTablesDialog; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.ActionEvent; @@ -37,18 +36,18 @@ import java.awt.event.KeyEvent; * @author nik */ public class ProjectStructureChooseLibrariesDialog extends ChooseLibrariesFromTablesDialog { + private final ClasspathPanel myClasspathPanel; private StructureConfigurableContext myContext; private Predicate myAcceptedLibraries; - private AddNewLibraryItemAction myNewLibraryAction; + private JButton myCreateLibraryButton; - public ProjectStructureChooseLibrariesDialog(JComponent parentComponent, - @Nullable Project project, + public ProjectStructureChooseLibrariesDialog(ClasspathPanel classpathPanel, StructureConfigurableContext context, - Predicate acceptedLibraries, AddNewLibraryItemAction newLibraryAction) { - super(parentComponent, "Choose Libraries", project, true); + Predicate acceptedLibraries) { + super(classpathPanel.getComponent(), "Choose Libraries", classpathPanel.getProject(), true); + myClasspathPanel = classpathPanel; myContext = context; myAcceptedLibraries = acceptedLibraries; - myNewLibraryAction = newLibraryAction; setOKButtonText("Add Selected"); init(); } @@ -95,6 +94,15 @@ public class ProjectStructureChooseLibrariesDialog extends ChooseLibrariesFromTa return new Action[]{getOKAction(), new CreateNewLibraryAction()}; } + @Override + protected JButton createJButtonForAction(Action action) { + final JButton button = super.createJButtonForAction(action); + if (action instanceof CreateNewLibraryAction) { + myCreateLibraryButton = button; + } + return button; + } + @Override protected LibrariesTreeNodeBase createLibraryDescriptor(NodeDescriptor parentDescriptor, Library library) { @@ -121,8 +129,7 @@ public class ProjectStructureChooseLibrariesDialog extends ChooseLibrariesFromTa @Override protected void doAction(ActionEvent e) { - close(CANCEL_EXIT_CODE); - myNewLibraryAction.execute(); + AddNewLibraryItemAction.chooseTypeAndExecute(myClasspathPanel, myContext, ProjectStructureChooseLibrariesDialog.this, myCreateLibraryButton); } } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryAction.java index 8d374c5ea6f1..eb01bd5fa240 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryAction.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.roots.ui.configuration.libraryEditor; +import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; @@ -99,7 +100,7 @@ public class CreateNewLibraryAction extends AnAction { return new AnAction[]{new CreateNewLibraryAction(text, Icons.LIBRARY_ICON, null, librariesConfigurable, project)}; } List actions = new ArrayList(); - actions.add(new CreateNewLibraryAction("Java", Icons.LIBRARY_ICON, null, librariesConfigurable, project)); + actions.add(new CreateNewLibraryAction(IdeBundle.message("create.default.library.type.action.name"), Icons.LIBRARY_ICON, null, librariesConfigurable, project)); for (LibraryType type : extensions) { actions.add(new CreateNewLibraryAction(type.getCreateActionName(), type.getIcon(), type, librariesConfigurable, project)); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java index c953df9490ed..e085da3d4450 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java @@ -17,6 +17,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.roots.impl.libraries.LibraryTableBase; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; @@ -67,8 +68,8 @@ public class CreateNewLibraryDialog extends LibraryEditorDialogBase { } public Library createLibrary() { - final LibraryTable.ModifiableModel modifiableModel = getTableModifiableModel(); - final Library library = modifiableModel.createLibrary(myLibraryEditor.getName()); + final LibraryTableBase.ModifiableModelEx modifiableModel = (LibraryTableBase.ModifiableModelEx)getTableModifiableModel(); + final Library library = modifiableModel.createLibrary(myLibraryEditor.getName(), myLibraryEditor.getType()); final Library.ModifiableModel model = library.getModifiableModel(); myLibraryEditor.apply(model); new WriteAction() { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryType.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryType.java index f0b622d4329d..73e4a0b741c1 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryType.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryType.java @@ -16,6 +16,7 @@ package com.intellij.openapi.roots.libraries; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent; import com.intellij.openapi.roots.libraries.ui.LibraryPropertiesEditor; import com.intellij.openapi.roots.libraries.ui.LibraryRootsComponentDescriptor; @@ -50,6 +51,10 @@ public abstract class LibraryType

extends LibraryPr @NotNull public abstract P createDefaultProperties(); + public boolean isSuitableForModuleType(@NotNull ModuleType moduleType) { + return true; + } + /** * Override this method to customize the library roots editor * @return {@link com.intellij.openapi.roots.libraries.ui.LibraryRootsComponentDescriptor} instance diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 4b04dd00875b..9d3e74a5e995 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -984,6 +984,9 @@ setup.library.dialog.title=Setup Library label.library.will.be.created.description.text={0} level library {1} with {2} file(s) will be created new.library.file.chooser.title=New Library Files new.library.file.chooser.description=Select jar files in which library classes are located + +create.default.library.type.action.name=Java + file.chooser.show.path=Show path file.chooser.hide.path=Hide path file.chooser.hide.path.tooltip.text=Show/Hide path text field