blob: 26fd82b20e7d95f4c7671cd19021bba392997f50 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.ant.config.impl.configuration;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.config.impl.AntInstallation;
import com.intellij.lang.ant.config.impl.AntReference;
import com.intellij.lang.ant.config.impl.GlobalAntConfiguration;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.config.AbstractProperty;
import com.intellij.util.config.StorageAccessors;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
public class AntSetPanel {
private final Form myForm;
private final GlobalAntConfiguration myAntConfiguration;
public AntSetPanel() {
this(GlobalAntConfiguration.getInstance());
}
AntSetPanel(GlobalAntConfiguration antConfiguration) {
myAntConfiguration = antConfiguration;
myForm = new Form(antConfiguration);
}
@Nullable
public AntInstallation showDialog(JComponent parent) {
final DialogWrapper dialog = new MyDialog(parent);
dialog.show();
if (!dialog.isOK()) {
return null;
}
apply();
return myForm.getSelectedAnt();
}
void reset() {
myForm.setAnts(myAntConfiguration.getConfiguredAnts().values());
}
void apply() {
for (AntInstallation ant : myForm.getRemovedAnts()) {
myAntConfiguration.removeConfiguration(ant);
}
final Map<AntReference, AntInstallation> currentAnts = myAntConfiguration.getConfiguredAnts();
for (AntInstallation installation : currentAnts.values()) {
installation.updateClasspath();
}
for (AntInstallation ant : myForm.getAddedAnts()) {
myAntConfiguration.addConfiguration(ant);
}
myForm.applyModifications();
}
public void setSelection(AntInstallation antInstallation) {
myForm.selectAnt(antInstallation);
}
public JComponent getComponent() {
return myForm.getComponent();
}
private static class Form implements AntUIUtil.PropertiesEditor<AntInstallation> {
private final Splitter mySplitter = new Splitter(false);
private final StorageAccessors myAccessors = StorageAccessors.createGlobal("antConfigurations");
private final RightPanel myRightPanel;
private final AnActionListEditor<AntInstallation> myAnts = new AnActionListEditor<AntInstallation>();
private final UIPropertyBinding.Composite myBinding = new UIPropertyBinding.Composite();
private final EditPropertyContainer myGlobalWorkingProperties;
private final Map<AntInstallation, EditPropertyContainer> myWorkingProperties = new HashMap<AntInstallation, EditPropertyContainer>();
private AntInstallation myCurrent;
private final PropertyChangeListener myImmediateUpdater = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
myBinding.apply(getProperties(myCurrent));
myAnts.updateItem(myCurrent);
}
};
public Form(final GlobalAntConfiguration antInstallation) {
mySplitter.setProportion(myAccessors.getFloat("splitter", 0.3f));
mySplitter.setShowDividerControls(true);
mySplitter.setFirstComponent(myAnts);
myGlobalWorkingProperties = new EditPropertyContainer(antInstallation.getProperties());
myRightPanel = new RightPanel(myBinding, myImmediateUpdater);
mySplitter.setSecondComponent(myRightPanel.myWholePanel);
myAnts.addAddAction(new NewAntFactory(myAnts));
myAnts.addRemoveButtonForAnt(antInstallation.IS_USER_ANT, AntBundle.message("remove.action.name"));
myAnts.actionsBuilt();
JList list = myAnts.getList();
list.setCellRenderer(new AntUIUtil.AntInstallationRenderer(this));
list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (myCurrent != null) myBinding.apply(getProperties(myCurrent));
myCurrent = myAnts.getSelectedItem();
if (myCurrent == null) {
myBinding.loadValues(AbstractProperty.AbstractPropertyContainer.EMPTY);
myBinding.beDisabled();
}
else {
if (antInstallation.IS_USER_ANT.value(myCurrent)) {
myBinding.beEnabled();
}
else {
myBinding.beDisabled();
}
myBinding.loadValues(getProperties(myCurrent));
}
}
});
}
public JList getAntsList() {
return myAnts.getList();
}
public JComponent getComponent() {
return mySplitter;
}
public AntInstallation getSelectedAnt() {
return myAnts.getSelectedItem();
}
public void setAnts(Collection<AntInstallation> antInstallations) {
myAnts.setItems(antInstallations);
}
public void applyModifications() {
if (myCurrent != null) myBinding.apply(getProperties(myCurrent));
ArrayList<AbstractProperty> properties = new ArrayList<AbstractProperty>();
myBinding.addAllPropertiesTo(properties);
for (AntInstallation ant : myWorkingProperties.keySet()) {
EditPropertyContainer container = myWorkingProperties.get(ant);
container.apply();
}
myGlobalWorkingProperties.apply();
}
public void selectAnt(AntInstallation antInstallation) {
myAnts.setSelection(antInstallation);
}
public ArrayList<AntInstallation> getAddedAnts() {
return myAnts.getAdded();
}
public ArrayList<AntInstallation> getRemovedAnts() {
return myAnts.getRemoved();
}
public EditPropertyContainer getProperties(AntInstallation ant) {
EditPropertyContainer properties = myWorkingProperties.get(ant);
if (properties != null) return properties;
properties = new EditPropertyContainer(myGlobalWorkingProperties, ant.getProperties());
myWorkingProperties.put(ant, properties);
return properties;
}
private static class RightPanel {
private JLabel myNameLabel;
private JLabel myHome;
private JTextField myName;
private AntClasspathEditorPanel myClasspath;
private JPanel myWholePanel;
public RightPanel(UIPropertyBinding.Composite binding, PropertyChangeListener immediateUpdater) {
myNameLabel.setLabelFor(myName);
binding.addBinding(myClasspath.setClasspathProperty(AntInstallation.CLASS_PATH));
binding.bindString(myHome, AntInstallation.HOME_DIR);
binding.bindString(myName, AntInstallation.NAME).addChangeListener(immediateUpdater);
}
}
}
private static class NewAntFactory implements Factory<AntInstallation> {
private final AnActionListEditor<AntInstallation> myParent;
public NewAntFactory(AnActionListEditor<AntInstallation> parent) {
myParent = parent;
}
public AntInstallation create() {
FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
VirtualFile file = FileChooser.chooseFile(descriptor, myParent, null, null);
if (file == null) return null;
try {
final AntInstallation inst = AntInstallation.fromHome(file.getPresentableUrl());
adjustName(inst);
return inst;
}
catch (AntInstallation.ConfigurationException e) {
Messages.showErrorDialog(myParent, e.getMessage(), AntBundle.message("ant.setup.dialog.title"));
return null;
}
}
private void adjustName(final AntInstallation justCreated) {
int nameIndex = 0;
String adjustedName = justCreated.getName();
final ListModel model = myParent.getList().getModel();
int idx = 0;
while (idx < model.getSize()) {
final AntInstallation inst = (AntInstallation)model.getElementAt(idx++);
if (adjustedName.equals(inst.getName())) {
adjustedName = justCreated.getName() + " (" + (++nameIndex) + ")";
idx = 0; // search from beginning
}
}
if (!adjustedName.equals(justCreated.getName())) {
justCreated.setName(adjustedName);
}
}
}
private class MyDialog extends DialogWrapper {
public MyDialog(final JComponent parent) {
super(parent, true);
setTitle(AntBundle.message("configure.ant.dialog.title"));
init();
}
@Nullable
protected JComponent createCenterPanel() {
return myForm.getComponent();
}
@NonNls
protected String getDimensionServiceKey() {
return "antSetDialogDimensionKey";
}
public JComponent getPreferredFocusedComponent() {
return myForm.getAntsList();
}
protected void doOKAction() {
final Set<String> names = new HashSet<String>();
final ListModel model = myForm.getAntsList().getModel();
for (int idx = 0; idx < model.getSize(); idx++) {
final AntInstallation inst = (AntInstallation)model.getElementAt(idx);
final String name = AntInstallation.NAME.get(myForm.getProperties(inst));
if (names.contains(name)) {
Messages.showErrorDialog("Duplicate ant installation name: \"" + name+ "\"", getTitle());
return;
}
names.add(name);
}
super.doOKAction();
}
}
}