improved ui for framework libraries setup

This commit is contained in:
nik
2010-09-30 12:02:49 +04:00
parent b57ddf15ba
commit bfc2aac351
13 changed files with 295 additions and 157 deletions
@@ -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++) {
@@ -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();
}
}
@@ -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();
}
}
@@ -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<Library, ExistingLibraryEditor> myExistingLibraryEditors = new HashMap<Library, ExistingLibraryEditor>();
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<Library> 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
@@ -30,7 +30,7 @@
</constraints>
<properties/>
</component>
<component id="2bb99" class="javax.swing.JLabel">
<component id="2bb99" class="javax.swing.JLabel" binding="myLevelLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<LibrariesContainer.LibraryLevel, String> levels = new HashMap<LibrariesContainer.LibraryLevel, String>();
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<LibrariesContainer.LibraryLevel, String> levels = new HashMap<LibrariesContainer.LibraryLevel, String>();
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>(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>(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() {
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.facet.impl.ui.libraries.LibraryOptionsPanel">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="584" height="261"/>
@@ -22,27 +22,19 @@
</properties>
</component>
<component id="f63e3" class="javax.swing.JRadioButton" binding="myDoNotCreateRadioButton">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Do &amp;not create new library"/>
</properties>
</component>
<component id="46359" class="javax.swing.JRadioButton">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Pick up files from &amp;disk"/>
<text value="Setup library &amp;later"/>
</properties>
</component>
<vspacer id="79970">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="71da4" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="71da4" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -50,13 +42,13 @@
<properties/>
<border type="none"/>
<children>
<component id="4dbad" class="javax.swing.JRadioButton" binding="myUseExistingLibraryRadioButton">
<component id="4dbad" class="javax.swing.JRadioButton">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text value="&amp;Use existing library"/>
<text value="&amp;Use library"/>
</properties>
</component>
<component id="6d530" class="javax.swing.JComboBox" binding="myExistingLibraryComboBox">
@@ -67,14 +59,22 @@
</component>
<hspacer id="a5d26">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="eaf39" class="javax.swing.JButton" binding="myCreateButton" default-binding="true">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Create..."/>
</properties>
</component>
</children>
</grid>
<grid id="7ea1" binding="myConfigurationPanel" layout-manager="CardLayout" hgap="0" vgap="0">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -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<Library> myLibraries;
private final SortedComboBoxModel<LibraryEditor> myLibraryComboBoxModel;
private enum Choice {
USE_EXISTING,
USE_LIBRARY,
DOWNLOAD,
PICK_FILES,
DO_NOT_CREATE
SETUP_LIBRARY_LATER
}
private RadioButtonEnumModel<Choice> myButtonEnumModel;
public LibraryOptionsPanel(@NotNull LibraryCompositionSettings settings,
@NotNull LibrariesContainer librariesContainer,
@NotNull final LibrariesContainer librariesContainer,
final boolean showDoNotCreateOption) {
mySettings = settings;
myLibrariesContainer = librariesContainer;
myLibraries = calculateSuitableLibraries();
List<Library> 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<Library> model = new SortedComboBoxModel<Library>(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<LibraryEditor>(new Comparator<LibraryEditor>() {
@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 : "<unnamed>");
}
}
});
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 = "<b>Error:</b> library is not specified";
}
else {
else if (item instanceof NewLibraryEditor) {
final LibraryEditor libraryEditor = (LibraryEditor)item;
message = MessageFormat.format("{0} level library <b>{1}</b>" +
" with {2} file(s) will be created",
mySettings.getLibraryLevel(),
mySettings.getLibraryName(),
libraryEditor.getName(),
libraryEditor.getFiles(OrderRootType.CLASSES).length);
}
else {
message = MessageFormat.format("<b>{0}</b> 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("<html>" + message + "</html>");
}
@@ -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);
}
@@ -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 {
@@ -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);
}
@@ -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<String>() {
@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<Object, String>() {
@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;
@@ -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<LibraryTableModifiableModelProvider> getCustomLibrariesProviders() {
return ContainerUtil.map2List(LibraryTablesRegistrar.getInstance().getCustomLibraryTables(), new NotNullFunction<LibraryTable, LibraryTableModifiableModelProvider>() {
@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)) {
@@ -63,13 +63,18 @@ public class UniqueNameGenerator implements Condition<String> {
}
public static String generateUniqueName(final String defaultName, final String prefix, final String suffix, final Condition<String> 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<String> 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<String> {
}
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;
}