From bfc2aac3518140f9b5bd58e673fd91fe9c79da0d Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 30 Sep 2010 12:01:56 +0400 Subject: [PATCH] improved ui for framework libraries setup --- .../libraries/DownloadingOptionsDialog.java | 6 +- .../impl/ui/libraries/EditLibraryDialog.java | 21 ++- .../FacetLibrariesValidatorImpl.java | 23 ++- .../libraries/LibraryCompositionSettings.java | 66 +++---- .../libraries/LibraryNameAndLevelPanel.form | 2 +- .../libraries/LibraryNameAndLevelPanel.java | 52 +++--- .../ui/libraries/LibraryOptionsPanel.form | 32 ++-- .../ui/libraries/LibraryOptionsPanel.java | 161 +++++++++++++----- .../FrameworkSupportNode.java | 3 +- .../projectRoot/LibrariesContainer.java | 7 + .../LibrariesContainerFactory.java | 54 +++++- .../StructureConfigurableContext.java | 12 -- .../util/text/UniqueNameGenerator.java | 13 +- 13 files changed, 295 insertions(+), 157 deletions(-) diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/DownloadingOptionsDialog.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/DownloadingOptionsDialog.java index 75192eabbff3..f28a7b5ecdbf 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/DownloadingOptionsDialog.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/DownloadingOptionsDialog.java @@ -67,9 +67,8 @@ public class DownloadingOptionsDialog extends DialogWrapper { myDownloadSourcesCheckBox.setSelected(settings.isDownloadSources()); myDownloadJavadocsCheckBox.setSelected(settings.isDownloadJavadocs()); - myNameAndLevelPanel = new LibraryNameAndLevelPanel(); + myNameAndLevelPanel = new LibraryNameAndLevelPanel(settings.getDownloadedLibraryName(), settings.getLibraryLevel()); myNameWrappingPanel.add(myNameAndLevelPanel.getPanel()); - myNameAndLevelPanel.reset(settings); init(); } @@ -85,7 +84,8 @@ public class DownloadingOptionsDialog extends DialogWrapper { @Override protected void doOKAction() { - myNameAndLevelPanel.apply(mySettings); + mySettings.setDownloadedLibraryName(myNameAndLevelPanel.getLibraryName()); + mySettings.setLibraryLevel(myNameAndLevelPanel.getLibraryLevel()); mySettings.setDirectoryForDownloadedLibrariesPath(myDirectoryField.getText()); LibraryInfo[] libraryInfos = mySettings.getLibraryInfos(); for (int i = 0, libraryInfosLength = libraryInfos.length; i < libraryInfosLength; i++) { diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/EditLibraryDialog.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/EditLibraryDialog.java index aa7e4f54b6e1..e14dd5b3e413 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/EditLibraryDialog.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/EditLibraryDialog.java @@ -15,7 +15,9 @@ */ package com.intellij.facet.impl.ui.libraries; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryRootsComponent; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Disposer; @@ -32,26 +34,26 @@ public class EditLibraryDialog extends DialogWrapper { private JPanel myNameAndLevelPanelWrapper; private final LibraryNameAndLevelPanel myNameAndLevelPanel; private LibraryCompositionSettings mySettings; + private LibraryEditor myLibraryEditor; private LibraryRootsComponent myLibraryRootsComponent; - public EditLibraryDialog(Component parent, LibraryCompositionSettings settings) { + public EditLibraryDialog(Component parent, LibraryCompositionSettings settings, final LibraryEditor libraryEditor) { super(parent, true); mySettings = settings; - myLibraryRootsComponent = LibraryRootsComponent.createComponent(settings.getOrCreateLibrary()); + myLibraryEditor = libraryEditor; + myLibraryRootsComponent = LibraryRootsComponent.createComponent(libraryEditor); Disposer.register(getDisposable(), myLibraryRootsComponent); - setTitle("Edit Library"); + final boolean newLibrary = libraryEditor instanceof NewLibraryEditor; + setTitle((newLibrary ? "Create" : "Edit") + " Library"); - myNameAndLevelPanel = new LibraryNameAndLevelPanel(); - myNameAndLevelPanel.reset(mySettings); + myNameAndLevelPanel = new LibraryNameAndLevelPanel(libraryEditor.getName(), newLibrary ? settings.getLibraryLevel() : null); init(); - } @Override protected JComponent createCenterPanel() { - JComponent editor = myLibraryRootsComponent.getComponent(); myEditorPanel.add(editor); myNameAndLevelPanelWrapper.add(myNameAndLevelPanel.getPanel()); @@ -60,7 +62,10 @@ public class EditLibraryDialog extends DialogWrapper { @Override protected void doOKAction() { - myNameAndLevelPanel.apply(mySettings); + myLibraryEditor.setName(myNameAndLevelPanel.getLibraryName()); + if (myLibraryEditor instanceof NewLibraryEditor) { + mySettings.setLibraryLevel(myNameAndLevelPanel.getLibraryLevel()); + } super.doOKAction(); } } diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java index 9a091a3d8389..d237547ff382 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java @@ -20,7 +20,9 @@ import com.intellij.facet.Facet; import com.intellij.facet.ui.FacetConfigurationQuickFix; import com.intellij.facet.ui.FacetValidatorsManager; import com.intellij.facet.ui.ValidationResult; -import com.intellij.facet.ui.libraries.*; +import com.intellij.facet.ui.libraries.FacetLibrariesValidator; +import com.intellij.facet.ui.libraries.FacetLibrariesValidatorDescription; +import com.intellij.facet.ui.libraries.LibraryInfo; import com.intellij.ide.IdeBundle; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; @@ -31,6 +33,7 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Processor; @@ -90,9 +93,7 @@ public class FacetLibrariesValidatorImpl extends FacetLibrariesValidator { LibraryInfo[] missingLibraries = info.getLibraryInfos(); VirtualFile baseDir = myContext.getModule().getProject().getBaseDir(); final String baseDirPath = baseDir != null ? baseDir.getPath() : ""; - LibraryCompositionSettings libraryCompositionSettings = new LibraryCompositionSettings(missingLibraries, - myDescription.getDefaultLibraryName(), baseDirPath); - return new ValidationResult(missingJars, new LibrariesQuickFix(libraryCompositionSettings)); + return new ValidationResult(missingJars, new LibrariesQuickFix(missingLibraries, myDescription.getDefaultLibraryName(), baseDirPath)); } private void onChange() { @@ -122,17 +123,23 @@ public class FacetLibrariesValidatorImpl extends FacetLibrariesValidator { } private class LibrariesQuickFix extends FacetConfigurationQuickFix { - private final LibraryCompositionSettings myLibrarySettings; + private LibraryInfo[] myMissingLibraries; + private String myDefaultLibraryName; + private String myBaseDirPath; - public LibrariesQuickFix(final LibraryCompositionSettings libraryCompositionSettings) { + public LibrariesQuickFix(LibraryInfo[] missingLibraries, String defaultLibraryName, String baseDirPath) { super(IdeBundle.message("missing.libraries.fix.button")); - myLibrarySettings = libraryCompositionSettings; + myMissingLibraries = missingLibraries; + myDefaultLibraryName = defaultLibraryName; + myBaseDirPath = baseDirPath; } public void run(final JComponent place) { - LibraryOptionsPanel panel = new LibraryOptionsPanel(myLibrarySettings, myContext.getLibrariesContainer(), false); + final LibraryCompositionSettings settings = new LibraryCompositionSettings(myMissingLibraries, myDefaultLibraryName, myBaseDirPath); + LibraryOptionsPanel panel = new LibraryOptionsPanel(settings, myContext.getLibrariesContainer(), false); LibraryCompositionDialog dialog = new LibraryCompositionDialog(place, panel); dialog.show(); + Disposer.dispose(settings); onChange(); } } diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java index 718b96ade000..a61793705b90 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryCompositionSettings.java @@ -21,16 +21,20 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor; import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author nik @@ -42,25 +46,31 @@ public class LibraryCompositionSettings implements Disposable { private String myDirectoryForDownloadedLibrariesPath; private boolean myDownloadLibraries = true; private LibrariesContainer.LibraryLevel myLibraryLevel = LibrariesContainer.LibraryLevel.PROJECT; - private String myLibraryName; + private String myDownloadedLibraryName; private boolean myDownloadSources = true; private boolean myDownloadJavadocs = true; - private NewLibraryEditor myLibraryEditor; + private NewLibraryEditor myNewLibraryEditor; private Library mySelectedLibrary; + private final String myDefaultLibraryName; + private Map myExistingLibraryEditors = new HashMap(); public LibraryCompositionSettings(final @NotNull LibraryInfo[] libraryInfos, final @NotNull String defaultLibraryName, final @NotNull String baseDirectoryForDownloadedFiles) { + myDefaultLibraryName = defaultLibraryName; myLibraryInfos = libraryInfos; myBaseDirectoryForDownloadedFiles = baseDirectoryForDownloadedFiles; - myLibraryName = defaultLibraryName; + myDownloadedLibraryName = defaultLibraryName; } - public void addFilesToLibrary(VirtualFile[] files, OrderRootType orderRootType) { - final NewLibraryEditor libraryEditor = getOrCreateLibrary(); - for (VirtualFile file : files) { - libraryEditor.addRoot(file, orderRootType); + public ExistingLibraryEditor getOrCreateEditor(@NotNull Library library) { + ExistingLibraryEditor libraryEditor = myExistingLibraryEditors.get(library); + if (libraryEditor == null) { + libraryEditor = new ExistingLibraryEditor(library, null); + Disposer.register(this, libraryEditor); + myExistingLibraryEditors.put(library, libraryEditor); } + return libraryEditor; } @NotNull @@ -68,6 +78,10 @@ public class LibraryCompositionSettings implements Disposable { return myLibraryInfos; } + public String getDefaultLibraryName() { + return myDefaultLibraryName; + } + @NotNull public String getBaseDirectoryForDownloadedFiles() { return myBaseDirectoryForDownloadedFiles; @@ -93,8 +107,8 @@ public class LibraryCompositionSettings implements Disposable { myLibraryLevel = libraryLevel; } - public void setLibraryName(final String libraryName) { - myLibraryName = libraryName; + public void setDownloadedLibraryName(final String downloadedLibraryName) { + myDownloadedLibraryName = downloadedLibraryName; } public String getDirectoryForDownloadedLibrariesPath() { @@ -108,18 +122,22 @@ public class LibraryCompositionSettings implements Disposable { if (myDownloadLibraries) { RequiredLibrariesInfo requiredLibraries = new RequiredLibrariesInfo(getLibraryInfos()); - VirtualFile[] jars = myLibraryEditor != null ? myLibraryEditor.getFiles(OrderRootType.CLASSES) : VirtualFile.EMPTY_ARRAY; + VirtualFile[] jars = myNewLibraryEditor != null ? myNewLibraryEditor.getFiles(OrderRootType.CLASSES) : VirtualFile.EMPTY_ARRAY; RequiredLibrariesInfo.RequiredClassesNotFoundInfo info = requiredLibraries.checkLibraries(jars, all); if (info != null) { LibraryDownloadInfo[] downloadingInfos = LibraryDownloader.getDownloadingInfos(info.getLibraryInfos()); if (downloadingInfos.length > 0) { LibraryDownloader downloader = new LibraryDownloader(downloadingInfos, null, parent, - getDirectoryForDownloadedLibrariesPath(), myLibraryName); + getDirectoryForDownloadedLibrariesPath(), myDownloadedLibraryName); VirtualFile[] files = downloader.download(); if (files.length != downloadingInfos.length) { return false; } - addFilesToLibrary(files, OrderRootType.CLASSES); + myNewLibraryEditor = new NewLibraryEditor(); + myNewLibraryEditor.setName(myDownloadedLibraryName); + for (VirtualFile file : files) { + myNewLibraryEditor.addRoot(file, OrderRootType.CLASSES); + } } } } @@ -129,10 +147,10 @@ public class LibraryCompositionSettings implements Disposable { @Nullable private Library createLibrary(final ModifiableRootModel rootModel, @Nullable LibrariesContainer additionalContainer) { - if (myLibraryEditor != null) { - VirtualFile[] roots = myLibraryEditor.getFiles(OrderRootType.CLASSES); + if (myNewLibraryEditor != null) { + VirtualFile[] roots = myNewLibraryEditor.getFiles(OrderRootType.CLASSES); return LibrariesContainerFactory.createLibrary(additionalContainer, LibrariesContainerFactory.createContainer(rootModel), - myLibraryName, myLibraryLevel, roots, VirtualFile.EMPTY_ARRAY); + myNewLibraryEditor.getName(), myLibraryLevel, roots, VirtualFile.EMPTY_ARRAY); } return null; } @@ -141,14 +159,13 @@ public class LibraryCompositionSettings implements Disposable { return myLibraryLevel; } - public String getLibraryName() { - return myLibraryName; + public String getDownloadedLibraryName() { + return myDownloadedLibraryName; } @Nullable public Library addLibraries(final @NotNull ModifiableRootModel rootModel, final @NotNull List addedLibraries, final @Nullable LibrariesContainer librariesContainer) { - Library library = createLibrary(rootModel, librariesContainer); if (library != null) { @@ -180,17 +197,8 @@ public class LibraryCompositionSettings implements Disposable { myDownloadJavadocs = downloadJavadocs; } - @Nullable - public NewLibraryEditor getLibraryEditor() { - return myLibraryEditor; - } - - @NotNull - public NewLibraryEditor getOrCreateLibrary() { - if (myLibraryEditor == null) { - myLibraryEditor = new NewLibraryEditor(); - } - return myLibraryEditor; + public void setNewLibraryEditor(NewLibraryEditor libraryEditor) { + myNewLibraryEditor = libraryEditor; } @Override diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.form b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.form index fcfa3744bbf1..25532e6d13c2 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.form +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.form @@ -30,7 +30,7 @@ - + diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.java index ecf8f059ee9c..8cfc93655f3b 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryNameAndLevelPanel.java @@ -18,6 +18,7 @@ package com.intellij.facet.impl.ui.libraries; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.ui.EnumComboBoxModel; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -31,34 +32,41 @@ class LibraryNameAndLevelPanel { private JTextField myLibraryNameField; private JComboBox myLevelComboBox; private JPanel myPanel; + private JLabel myLevelLabel; - LibraryNameAndLevelPanel() { - final Map levels = new HashMap(); - levels.put(LibrariesContainer.LibraryLevel.GLOBAL, ProjectBundle.message("combobox.item.global.library")); - levels.put(LibrariesContainer.LibraryLevel.PROJECT, ProjectBundle.message("combobox.item.project.library")); - levels.put(LibrariesContainer.LibraryLevel.MODULE, ProjectBundle.message("combobox.item.module.library")); - myLevelComboBox.setRenderer(new DefaultListCellRenderer() { - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - final Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (value instanceof LibrariesContainer.LibraryLevel) { - final LibrariesContainer.LibraryLevel level = (LibrariesContainer.LibraryLevel)value; - setText(levels.get(level)); + LibraryNameAndLevelPanel(String libraryName, @Nullable LibrariesContainer.LibraryLevel level) { + if (level != null) { + final Map levels = new HashMap(); + levels.put(LibrariesContainer.LibraryLevel.GLOBAL, ProjectBundle.message("combobox.item.global.library")); + levels.put(LibrariesContainer.LibraryLevel.PROJECT, ProjectBundle.message("combobox.item.project.library")); + levels.put(LibrariesContainer.LibraryLevel.MODULE, ProjectBundle.message("combobox.item.module.library")); + myLevelComboBox.setRenderer(new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + final Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof LibrariesContainer.LibraryLevel) { + final LibrariesContainer.LibraryLevel level = (LibrariesContainer.LibraryLevel)value; + setText(levels.get(level)); + } + return component; } - return component; - } - }); + }); + myLevelComboBox.setModel(new EnumComboBoxModel(LibrariesContainer.LibraryLevel.class)); + myLevelComboBox.setSelectedItem(level); + } + else { + myLevelLabel.setVisible(false); + myLevelComboBox.setVisible(false); + } + myLibraryNameField.setText(libraryName); } - void reset(LibraryCompositionSettings settings) { - myLibraryNameField.setText(settings.getLibraryName()); - myLevelComboBox.setModel(new EnumComboBoxModel(LibrariesContainer.LibraryLevel.class)); - myLevelComboBox.setSelectedItem(settings.getLibraryLevel()); + public String getLibraryName() { + return myLibraryNameField.getText(); } - void apply(LibraryCompositionSettings settings) { - settings.setLibraryName(myLibraryNameField.getText()); - settings.setLibraryLevel((LibrariesContainer.LibraryLevel)myLevelComboBox.getSelectedItem()); + public LibrariesContainer.LibraryLevel getLibraryLevel() { + return (LibrariesContainer.LibraryLevel)myLevelComboBox.getSelectedItem(); } public JPanel getPanel() { diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form index f72f6a42294a..82b99543a602 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.form @@ -1,6 +1,6 @@
- + @@ -22,27 +22,19 @@ - - - - - - - - - + - + - + @@ -50,13 +42,13 @@ - + - + @@ -67,14 +59,22 @@ - + + + + + + + + + - + diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java index 5c6e48e6df28..3295318c47bf 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java @@ -17,19 +17,25 @@ package com.intellij.facet.impl.ui.libraries; import com.intellij.facet.ui.libraries.LibraryInfo; import com.intellij.ide.IdeBundle; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.roots.ui.configuration.LibrariesAlphaComparator; import com.intellij.openapi.roots.ui.configuration.ProjectStructureDialogCellAppearanceUtils; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; +import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.SortedComboBoxModel; +import com.intellij.util.Icons; import com.intellij.util.PathUtil; import com.intellij.util.ui.RadioButtonEnumModel; import org.jetbrains.annotations.NotNull; @@ -39,9 +45,12 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.io.File; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; /** @@ -52,30 +61,29 @@ public class LibraryOptionsPanel { private JPanel myPanel; private JButton myConfigureButton; private JComboBox myExistingLibraryComboBox; - private JRadioButton myUseExistingLibraryRadioButton; private JRadioButton myDoNotCreateRadioButton; private JPanel myConfigurationPanel; + private JButton myCreateButton; private ButtonGroup myButtonGroup; private final LibraryCompositionSettings mySettings; private final LibrariesContainer myLibrariesContainer; - private final List myLibraries; + private final SortedComboBoxModel myLibraryComboBoxModel; private enum Choice { - USE_EXISTING, + USE_LIBRARY, DOWNLOAD, - PICK_FILES, - DO_NOT_CREATE + SETUP_LIBRARY_LATER } private RadioButtonEnumModel myButtonEnumModel; public LibraryOptionsPanel(@NotNull LibraryCompositionSettings settings, - @NotNull LibrariesContainer librariesContainer, + @NotNull final LibrariesContainer librariesContainer, final boolean showDoNotCreateOption) { mySettings = settings; myLibrariesContainer = librariesContainer; - myLibraries = calculateSuitableLibraries(); + List libraries = calculateSuitableLibraries(); myButtonEnumModel = RadioButtonEnumModel.bindEnum(Choice.class, myButtonGroup); myButtonEnumModel.addActionListener(new ActionListener() { @@ -85,39 +93,92 @@ public class LibraryOptionsPanel { } }); - final boolean librariesFound = !myLibraries.isEmpty(); myDoNotCreateRadioButton.setVisible(showDoNotCreateOption); - myUseExistingLibraryRadioButton.setVisible(librariesFound); - myExistingLibraryComboBox.setVisible(librariesFound); - if (librariesFound) { - final SortedComboBoxModel model = new SortedComboBoxModel(LibrariesAlphaComparator.INSTANCE); - model.addAll(myLibraries); - myExistingLibraryComboBox.setModel(model); - myExistingLibraryComboBox.setSelectedIndex(0); - myExistingLibraryComboBox.setRenderer(new ColoredListCellRenderer() { - @Override - protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { - if (value instanceof Library) { - ProjectStructureDialogCellAppearanceUtils.forLibrary((Library)value, null).customize(this); - } - } - }); + myLibraryComboBoxModel = new SortedComboBoxModel(new Comparator() { + @Override + public int compare(LibraryEditor o1, LibraryEditor o2) { + final String name1 = o1.getName(); + final String name2 = o2.getName(); + return StringUtil.notNullize(name1).compareToIgnoreCase(StringUtil.notNullize(name2)); + } + }); + for (Library library : libraries) { + ExistingLibraryEditor libraryEditor = librariesContainer.getLibraryEditor(library); + if (libraryEditor == null) { + libraryEditor = mySettings.getOrCreateEditor(library); + } + myLibraryComboBoxModel.add(libraryEditor); } - myButtonEnumModel.setSelected(librariesFound ? Choice.USE_EXISTING : Choice.DOWNLOAD); + myExistingLibraryComboBox.setModel(myLibraryComboBoxModel); + if (libraries.isEmpty()) { + myLibraryComboBoxModel.add(null); + } + myExistingLibraryComboBox.setSelectedIndex(0); + myExistingLibraryComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED && e.getItem() != null) { + myButtonEnumModel.setSelected(Choice.USE_LIBRARY); + } + updateState(); + } + }); + myExistingLibraryComboBox.setRenderer(new ColoredListCellRenderer() { + @Override + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + if (value == null) { + append("[No library selected]"); + } + else if (value instanceof ExistingLibraryEditor) { + ProjectStructureDialogCellAppearanceUtils.forLibrary(((ExistingLibraryEditor)value).getLibrary(), null).customize(this); + } + else if (value instanceof NewLibraryEditor) { + setIcon(Icons.LIBRARY_ICON); + final String name = ((NewLibraryEditor)value).getName(); + append(name != null ? name : ""); + } + } + }); + myButtonEnumModel.setSelected(libraries.isEmpty() ? Choice.DOWNLOAD : Choice.USE_LIBRARY); + myCreateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final VirtualFile[] roots = showFileChooser(); + if (roots.length > 0) { + final NewLibraryEditor libraryEditor = new NewLibraryEditor(); + libraryEditor.setName(librariesContainer.suggestUniqueLibraryName(mySettings.getDefaultLibraryName())); + for (VirtualFile root : roots) { + libraryEditor.addRoot(root, OrderRootType.CLASSES); + } + if (myLibraryComboBoxModel.get(0) == null) { + myLibraryComboBoxModel.remove(0); + } + myLibraryComboBoxModel.add(libraryEditor); + myLibraryComboBoxModel.setSelectedItem(libraryEditor); + myButtonEnumModel.setSelected(Choice.USE_LIBRARY); + } + } + }); myConfigureButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { switch (myButtonEnumModel.getSelected()) { case DOWNLOAD: new DownloadingOptionsDialog(myPanel, mySettings).show(); break; - case PICK_FILES: - if (mySettings.getLibraryEditor() == null) { - VirtualFile[] files = showFileChooser(); - mySettings.addFilesToLibrary(files, OrderRootType.CLASSES); + case USE_LIBRARY: + final Object item = myExistingLibraryComboBox.getSelectedItem(); + if (item instanceof LibraryEditor) { + EditLibraryDialog dialog = new EditLibraryDialog(myPanel, mySettings, (LibraryEditor)item); + dialog.show(); + if (item instanceof ExistingLibraryEditor) { + new WriteAction() { + protected void run(final Result result) { + ((ExistingLibraryEditor)item).commit(); + } + }.execute(); + } } - EditLibraryDialog dialog = new EditLibraryDialog(myPanel, mySettings); - dialog.show(); break; default: break; @@ -163,34 +224,39 @@ public class LibraryOptionsPanel { } private void updateState() { - myMessageLabel.setForeground(Color.black); - + myMessageLabel.setIcon(null); String message = ""; boolean showConfigurePanel = true; switch (myButtonEnumModel.getSelected()) { case DOWNLOAD: message = getDownloadFilesMessage(); break; - case PICK_FILES: - NewLibraryEditor libraryEditor = mySettings.getLibraryEditor(); - if (libraryEditor == null) { - myMessageLabel.setForeground(Color.red); - message = "Press 'Configure' button to add classes to the library"; + case USE_LIBRARY: + final Object item = myExistingLibraryComboBox.getSelectedItem(); + if (item == null) { + myMessageLabel.setIcon(IconLoader.getIcon("/runConfigurations/configurationWarning.png")); + message = "Error: library is not specified"; } - else { + else if (item instanceof NewLibraryEditor) { + final LibraryEditor libraryEditor = (LibraryEditor)item; message = MessageFormat.format("{0} level library {1}" + " with {2} file(s) will be created", mySettings.getLibraryLevel(), - mySettings.getLibraryName(), + libraryEditor.getName(), libraryEditor.getFiles(OrderRootType.CLASSES).length); } + else { + message = MessageFormat.format("{0} library will be used", ((ExistingLibraryEditor)item).getName()); + } break; default: - //show the longest message on the hidden card to ensure that dialog won't jump if user selects another option - message = getDownloadFilesMessage(); showConfigurePanel = false; } + if (!showConfigurePanel) { + //show the longest message on the hidden card to ensure that dialog won't jump if user selects another option + message = getDownloadFilesMessage(); + } ((CardLayout)myConfigurationPanel.getLayout()).show(myConfigurationPanel, showConfigurePanel ? "configure" : "empty"); myMessageLabel.setText("" + message + ""); } @@ -210,16 +276,21 @@ public class LibraryOptionsPanel { mySettings.getLibraryInfos().length, path, mySettings.getLibraryLevel(), - mySettings.getLibraryName()); + mySettings.getDownloadedLibraryName()); } public LibraryCompositionSettings getSettings() { return mySettings; } - public void apply() { - mySettings.setSelectedExistingLibrary((Library)myExistingLibraryComboBox.getSelectedItem()); + final Object item = myExistingLibraryComboBox.getSelectedItem(); + if (item instanceof ExistingLibraryEditor) { + mySettings.setSelectedExistingLibrary(((ExistingLibraryEditor)item).getLibrary()); + } + else if (item instanceof NewLibraryEditor) { + mySettings.setNewLibraryEditor((NewLibraryEditor)item); + } mySettings.setDownloadLibraries(myButtonEnumModel.getSelected() == Choice.DOWNLOAD); } diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportNode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportNode.java index 2d5c1db0e884..18356364de25 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportNode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportNode.java @@ -122,8 +122,7 @@ public class FrameworkSupportNode extends CheckedTreeNode { if (myLibraryCompositionSettings == null || isObsolete(myLibraryCompositionSettings)) { final LibraryInfo[] libraries = getLibraries(); if (libraries.length != 0) { - myLibraryCompositionSettings = new LibraryCompositionSettings(libraries, myConfigurable.getSelectedVersion().getLibraryName(), myBaseDirForLibrariesGetter.compute() - ); + myLibraryCompositionSettings = new LibraryCompositionSettings(libraries, myConfigurable.getSelectedVersion().getLibraryName(), myBaseDirForLibrariesGetter.compute()); Disposer.register(myConfigurable, myLibraryCompositionSettings); } else { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java index 7b7cabfcf609..39a98803bef9 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainer.java @@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NonNls; @@ -52,4 +53,10 @@ public interface LibrariesContainer { Library createLibrary(@NotNull @NonNls String name, @NotNull LibraryLevel level, @NotNull VirtualFile[] classRoots, @NotNull VirtualFile[] sourceRoots); + + @NotNull + String suggestUniqueLibraryName(@NotNull String baseName); + + @Nullable + ExistingLibraryEditor getLibraryEditor(@NotNull Library library); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java index a5d4723d38af..a14670142748 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; @@ -22,16 +23,18 @@ 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.ui.configuration.LibraryTableModifiableModelProvider; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import com.intellij.util.text.UniqueNameGenerator; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; -import java.util.ArrayList; +import java.util.*; /** * @author nik @@ -96,16 +99,18 @@ public class LibrariesContainerFactory { } private static String getUniqueLibraryName(final String baseName, final LibraryTable.ModifiableModel model) { - String name = baseName; - int count = 2; - while (model.getLibraryByName(name) != null) { - name = baseName + " (" + count++ + ")"; - } - return name; + return UniqueNameGenerator.generateUniqueName(baseName, "", "", " (", ")", new Condition() { + @Override + public boolean value(String s) { + return model.getLibraryByName(s) == null; + } + }); } private abstract static class LibrariesContainerBase implements LibrariesContainer { + private UniqueNameGenerator myNameGenerator; + @NotNull public Library[] getAllLibraries() { Library[] libraries = getLibraries(LibraryLevel.GLOBAL); @@ -119,6 +124,20 @@ public class LibrariesContainerFactory { } return libraries; } + + @NotNull + @Override + public String suggestUniqueLibraryName(@NotNull String baseName) { + if (myNameGenerator == null) { + myNameGenerator = new UniqueNameGenerator(Arrays.asList(getAllLibraries()), new Function() { + @Override + public String fun(Object o) { + return ((Library)o).getName(); + } + }); + } + return myNameGenerator.generateUniqueName(baseName, "", "", " (", ")"); + } } @@ -204,6 +223,11 @@ public class LibrariesContainerFactory { } return createLibraryInTable(name, classRoots, sourceRoots, table); } + + @Override + public ExistingLibraryEditor getLibraryEditor(@NotNull Library library) { + return null; + } } private static class StructureConfigurableLibrariesContainer extends LibrariesContainerBase { @@ -234,6 +258,18 @@ public class LibrariesContainerFactory { return library; } + @Override + public ExistingLibraryEditor getLibraryEditor(@NotNull Library library) { + final LibraryTable table = library.getTable(); + if (table == null) return null; + + final LibraryTable.ModifiableModel model = myContext.getModifiableLibraryTable(table); + if (model instanceof LibrariesModifiableModel) { + return ((LibrariesModifiableModel)model).getLibraryEditor(library); + } + return null; + } + @Nullable public Project getProject() { return myProject; diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java index 6cfd45485a44..59f242bdc2a8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java @@ -23,13 +23,10 @@ import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil; 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.ui.configuration.LibraryTableModifiableModelProvider; import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorListener; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzer; import com.intellij.openapi.util.Disposer; -import com.intellij.util.NotNullFunction; -import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -116,15 +113,6 @@ public class StructureConfigurableContext implements Disposable, LibraryEditorLi } - public List getCustomLibrariesProviders() { - return ContainerUtil.map2List(LibraryTablesRegistrar.getInstance().getCustomLibraryTables(), new NotNullFunction() { - @NotNull - public LibraryTableModifiableModelProvider fun(final LibraryTable libraryTable) { - return createModifiableModelProvider(libraryTable.getTableLevel()); - } - }); - } - public LibraryTable.ModifiableModel getModifiableLibraryTable(@NotNull LibraryTable table) { final String tableLevel = table.getTableLevel(); if (tableLevel.equals(LibraryTableImplUtil.MODULE_LEVEL)) { diff --git a/platform/util/src/com/intellij/util/text/UniqueNameGenerator.java b/platform/util/src/com/intellij/util/text/UniqueNameGenerator.java index 4f3437ada320..6c379d85beec 100644 --- a/platform/util/src/com/intellij/util/text/UniqueNameGenerator.java +++ b/platform/util/src/com/intellij/util/text/UniqueNameGenerator.java @@ -63,13 +63,18 @@ public class UniqueNameGenerator implements Condition { } public static String generateUniqueName(final String defaultName, final String prefix, final String suffix, final Condition validator) { + return generateUniqueName(defaultName, prefix, suffix, "", "", validator); + } + + public static String generateUniqueName(final String defaultName, final String prefix, final String suffix, + final String beforeNumber, final String afterNumber, final Condition validator) { final String defaultFullName = prefix + defaultName + suffix; if (validator.value(defaultFullName)) { return defaultFullName; } for (int i = 2; ; i++) { - final String fullName = prefix + defaultName + i + suffix; + final String fullName = prefix + defaultName + beforeNumber + i + afterNumber + suffix; if (validator.value(fullName)) { return fullName; } @@ -77,7 +82,11 @@ public class UniqueNameGenerator implements Condition { } public String generateUniqueName(final String defaultName, final String prefix, final String suffix) { - final String result = generateUniqueName(defaultName, prefix, suffix, this); + return generateUniqueName(defaultName, prefix, suffix, "", ""); + } + + public String generateUniqueName(final String defaultName, final String prefix, final String suffix, final String beforeNumber, final String afterNumber) { + final String result = generateUniqueName(defaultName, prefix, suffix, beforeNumber, afterNumber, this); myExistingNames.add(result); return result; }