/* * Copyright 2013-2016 consulo.io * * 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 consulo.extension.ui; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkType; import com.intellij.openapi.projectRoots.SdkTypeId; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; import com.intellij.util.NullableFunction; import com.intellij.util.PairConsumer; import consulo.annotations.Exported; import consulo.annotations.RequiredReadAction; import consulo.module.extension.MutableModuleExtension; import consulo.module.extension.MutableModuleExtensionWithSdk; import consulo.module.extension.MutableModuleInheritableNamedPointer; import consulo.roots.ui.configuration.SdkComboBox; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.ItemEvent; import java.util.Collections; import java.util.Set; /** * @author VISTALL * @since 15.03.2015 */ public class ModuleExtensionSdkBoxBuilder<T extends MutableModuleExtension<?>> { @NotNull public static <T extends MutableModuleExtensionWithSdk<?>> ModuleExtensionSdkBoxBuilder createAndDefine(@NotNull T extension, @Nullable Runnable updater) { ModuleExtensionSdkBoxBuilder<T> builder = create(extension, updater); builder.sdkTypeClass(extension.getSdkTypeClass()); builder.sdkPointerFunc(dom -> dom.getInheritableSdk()); return builder; } @NotNull public static <T extends MutableModuleExtension<?>> ModuleExtensionSdkBoxBuilder<T> create(@NotNull T extension, @Nullable Runnable updater) { return new ModuleExtensionSdkBoxBuilder<>(extension).laterUpdater(updater); } @NotNull private NullableFunction<T, MutableModuleInheritableNamedPointer<Sdk>> mySdkPointerFunction; @NotNull private Condition<SdkTypeId> mySdkFilter = Conditions.alwaysTrue(); private final T myMutableModuleExtension; private String myLabelText = "SDK"; private Icon myNullItemIcon = null; private String myNullItemName = ProjectBundle.message("sdk.combo.box.item"); private Runnable myLaterUpdater; private PairConsumer<Sdk, Sdk> myPostConsumer; private ModuleExtensionSdkBoxBuilder(@NotNull T mutableModuleExtension) { myMutableModuleExtension = mutableModuleExtension; } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> sdkTypeClass(@NotNull final Class<? extends SdkTypeId> clazz) { mySdkFilter = sdkTypeId -> clazz.isAssignableFrom(sdkTypeId.getClass()); return this; } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> sdkTypes(@NotNull final Set<SdkType> sdkTypes) { mySdkFilter = sdkTypes::contains; return this; } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> sdkType(@NotNull final SdkType sdkType) { return sdkTypes(Collections.singleton(sdkType)); } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> sdkPointerFunc(@NotNull NullableFunction<T, MutableModuleInheritableNamedPointer<Sdk>> function) { mySdkPointerFunction = function; return this; } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> labelText(@NotNull String labelText) { myLabelText = labelText; return this; } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> laterUpdater(@Nullable Runnable runnable) { myLaterUpdater = runnable; return this; } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> postConsumer(@NotNull PairConsumer<Sdk, Sdk> consumer) { myPostConsumer = consumer; return this; } @NotNull @Exported public ModuleExtensionSdkBoxBuilder<T> nullItem(@Nullable String name, @Nullable Icon icon) { myNullItemName = name; myNullItemIcon = icon; return this; } @NotNull @RequiredReadAction public JComponent build() { final ProjectSdksModel projectSdksModel = ProjectStructureConfigurable.getInstance(myMutableModuleExtension.getProject()).getProjectSdksModel(); final SdkComboBox comboBox = new SdkComboBox(projectSdksModel, mySdkFilter, null, myNullItemName, myNullItemIcon); comboBox.insertModuleItems(myMutableModuleExtension, mySdkPointerFunction); final MutableModuleInheritableNamedPointer<Sdk> inheritableSdk = mySdkPointerFunction.fun(myMutableModuleExtension); assert inheritableSdk != null; if (inheritableSdk.isNull()) { comboBox.setSelectedNoneSdk(); } else { final String sdkInheritModuleName = inheritableSdk.getModuleName(); if (sdkInheritModuleName != null) { final Module sdkInheritModule = inheritableSdk.getModule(); if (sdkInheritModule == null) { comboBox.addInvalidModuleItem(sdkInheritModuleName); } comboBox.setSelectedModule(sdkInheritModuleName); } else { comboBox.setSelectedSdk(inheritableSdk.getName()); } } comboBox.addItemListener(e -> { if (e.getStateChange() == ItemEvent.SELECTED) { Sdk oldValue = inheritableSdk.get(); inheritableSdk.set(comboBox.getSelectedModuleName(), comboBox.getSelectedSdkName()); if (myPostConsumer != null) { Sdk sdk = inheritableSdk.get(); myPostConsumer.consume(oldValue, sdk); } if (myLaterUpdater != null) { SwingUtilities.invokeLater(myLaterUpdater); } } }); return LabeledComponent.left(comboBox, myLabelText); } }