package net.jangaroo.ide.idea.ui;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.ProjectJdksEditor;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.util.ArrayUtil;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JList;
import com.intellij.util.PlatformIcons;
import net.jangaroo.ide.idea.JangarooSdkType;
import org.jetbrains.annotations.Nullable;
import static net.jangaroo.ide.idea.JangarooSdkUtils.getSdkType;
public class JangarooSdkComboBoxWithBrowseButton extends ComboboxWithBrowseButton {
public static final Condition<Sdk> JANGAROO_SDK = new Condition<Sdk>() {
public boolean value(Sdk sdk) {
return sdk != null && getSdkType(sdk) instanceof JangarooSdkType;
}
};
private final Condition<Sdk> mySdkEvaluator;
private ModuleSdk myModuleSdk = new ModuleSdk();
private boolean myShowModuleSdk = false;
public JangarooSdkComboBoxWithBrowseButton() {
this(JANGAROO_SDK);
}
public JangarooSdkComboBoxWithBrowseButton(Condition<Sdk> sdkEvaluator) {
mySdkEvaluator = sdkEvaluator;
rebuildSdkListAndSelectSdk(null);
final JComboBox sdkCombo = getComboBox();
sdkCombo.setRenderer(new DefaultListCellRenderer() {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if ((value instanceof JangarooSdkComboBoxWithBrowseButton.ModuleSdk)) {
Sdk sdk = ((JangarooSdkComboBoxWithBrowseButton.ModuleSdk)value).mySdk;
if (sdk == null) {
if (sdkCombo.isEnabled()) {
setText("<html><font color='red'>Module SDK [not set]</font></html>");
setIcon(PlatformIcons.ERROR_INTRODUCTION_ICON);
} else {
setText("Module SDK [not set]");
setIcon(IconLoader.getDisabledIcon(PlatformIcons.ERROR_INTRODUCTION_ICON));
}
} else {
setText("Module SDK [" + sdk.getName() + "]");
setIcon(getSdkType(((JangarooSdkComboBoxWithBrowseButton.ModuleSdk)value).mySdk).getIcon());
}
} else if ((value instanceof String)) {
if (sdkCombo.isEnabled()) {
setText("<html><font color='red'>" + value + " [Invalid]</font></html>");
setIcon(PlatformIcons.ERROR_INTRODUCTION_ICON);
} else {
setText(value + " [Invalid]");
setIcon(IconLoader.getDisabledIcon(PlatformIcons.ERROR_INTRODUCTION_ICON));
}
} else if ((value instanceof Sdk)) {
setText(((Sdk)value).getName());
setIcon(getSdkType(((Sdk)value)).getIcon());
} else if (sdkCombo.isEnabled()) {
setText("<html><font color='red'>[none]</font></html>");
} else {
setText("[none]");
}
return this;
}
});
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(sdkCombo));
if (project == null) {
project = ProjectManager.getInstance().getDefaultProject();
}
ProjectJdksEditor editor = new ProjectJdksEditor(null, project, JangarooSdkComboBoxWithBrowseButton.this);
editor.show();
if (editor.isOK()) {
Sdk selectedSdk = editor.getSelectedJdk();
if (mySdkEvaluator.value(selectedSdk)) {
rebuildSdkListAndSelectSdk(selectedSdk);
} else {
rebuildSdkListAndSelectSdk(null);
if (selectedSdk != null)
Messages.showErrorDialog(JangarooSdkComboBoxWithBrowseButton.this,
"Jangaroo SDK " + selectedSdk.getName() + " cannot be selected.", "Select Jangaroo SDK");
}
}
}
});
}
private void rebuildSdkListAndSelectSdk(@Nullable Sdk selectedSdk) {
String previousSelectedSdkName = getSelectedSdkRaw();
List<Sdk> sdkList = new ArrayList<Sdk>();
if (myShowModuleSdk) {
sdkList.add(myModuleSdk.mySdk);
}
Sdk[] sdks = ProjectJdkTable.getInstance().getAllJdks();
for (Sdk sdk : sdks) {
if (mySdkEvaluator.value(sdk)) {
sdkList.add(sdk);
}
}
if (!sdkList.isEmpty()) {
getComboBox().setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(sdkList)));
if (selectedSdk != null) {
setSelectedSdkRaw(selectedSdk.getName(), false);
} else if (previousSelectedSdkName != null)
setSelectedSdkRaw(previousSelectedSdkName, false);
} else {
getComboBox().setModel(new DefaultComboBoxModel(new Object[]{null}));
}
}
public void addComboboxListener(final Listener listener) {
getComboBox().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
listener.stateChanged();
}
});
getComboBox().addPropertyChangeListener("model", new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
listener.stateChanged();
}
});
}
@Nullable
public Sdk getSelectedSdk() {
Object selectedItem = getComboBox().getSelectedItem();
if ((selectedItem instanceof ModuleSdk)) {
return ((ModuleSdk)selectedItem).mySdk;
}
if ((selectedItem instanceof Sdk)) {
return (Sdk)selectedItem;
}
return null;
}
public String getSelectedSdkRaw() {
Object selectedItem = getComboBox().getSelectedItem();
if ((selectedItem instanceof ModuleSdk)) {
return "Module SDK";
}
if ((selectedItem instanceof Sdk)) {
return ((Sdk)selectedItem).getName();
}
if ((selectedItem instanceof String)) {
return (String)selectedItem;
}
return "";
}
public void setSelectedSdkRaw(String sdkName) {
setSelectedSdkRaw(sdkName, true);
}
private void setSelectedSdkRaw(String sdkName, boolean addErrorItemIfSdkNotFound) {
JComboBox combo = getComboBox();
if ("Module SDK".equals(sdkName)) {
combo.setSelectedItem(myModuleSdk);
return;
}
for (int i = 0; i < combo.getItemCount(); i++) {
Object item = combo.getItemAt(i);
if (((item instanceof Sdk)) && (((Sdk)item).getName().equals(sdkName))) {
combo.setSelectedItem(item);
return;
}
}
if (addErrorItemIfSdkNotFound) {
List<Object> items = new ArrayList<Object>();
items.add(sdkName);
for (int i = 0; i < combo.getItemCount(); i++) {
Object item = combo.getItemAt(i);
if (!(item instanceof String)) {
items.add(item);
}
}
combo.setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(items)));
}
}
public void showModuleSdk(boolean showModuleSdk) {
if (myShowModuleSdk != showModuleSdk) {
myShowModuleSdk = showModuleSdk;
Object selectedItem = getComboBox().getSelectedItem();
rebuildSdkListAndSelectSdk(null);
if ((selectedItem instanceof String))
setSelectedSdkRaw((String)selectedItem, true);
}
}
public void setModuleSdk(Sdk sdk) {
if (sdk != myModuleSdk.mySdk)
myModuleSdk.mySdk = sdk;
}
private static class ModuleSdk {
private Sdk mySdk;
}
public static abstract interface Listener {
public abstract void stateChanged();
}
}