/* * Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan * * 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.goide.configuration; import com.goide.GoConstants; import com.goide.project.GoBuildTargetSettings; import com.goide.sdk.GoSdkService; import com.goide.util.GoUtil; import com.intellij.ProjectTopics; import com.intellij.openapi.Disposable; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.ModuleRootAdapter; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.MutableCollectionComboBoxModel; import com.intellij.ui.RawCommandLineEditor; import com.intellij.util.ArrayUtil; import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.event.ActionListener; import java.util.Arrays; import java.util.Collection; import java.util.List; public class GoBuildTagsUI implements Disposable { private static final String ENABLED = "Enabled"; private static final String DISABLED = "Disabled"; private JPanel myPanel; private ComboBox myOSCombo; private ComboBox myArchCombo; private ComboBox myGoVersionCombo; private ComboBox myCompilerCombo; private ComboBox myCgoCombo; private RawCommandLineEditor myCustomTagsField; @SuppressWarnings("unused") private JTextPane myDescriptionPane; @NotNull private final MutableCollectionComboBoxModel<String> myCgoComboModel; @NotNull private final String myDefaultOSValue; @NotNull private final String myDefaultArchValue; @NotNull private String myDefaultCgo; @NotNull private String myDefaultGoVersion = ""; @SuppressWarnings("unchecked") public GoBuildTagsUI() { myPanel.setBorder(IdeBorderFactory.createTitledBorder("Build tags")); myDefaultOSValue = "Default (" + GoUtil.systemOS() + ")"; myDefaultArchValue = "Default (" + GoUtil.systemArch() + ")"; myDefaultCgo = "Default (" + cgo(GoUtil.systemCgo(myDefaultOSValue, myDefaultArchValue)) + ")"; myCustomTagsField.setDialogCaption("Custom Build Tags"); myOSCombo.setModel(createModel(GoConstants.KNOWN_OS, myDefaultOSValue)); myArchCombo.setModel(createModel(GoConstants.KNOWN_ARCH, myDefaultArchValue)); myCgoComboModel = createModel(ContainerUtil.newArrayList(ENABLED, DISABLED), myDefaultCgo); myCgoCombo.setModel(myCgoComboModel); myCompilerCombo.setModel(createModel(GoConstants.KNOWN_COMPILERS, GoBuildTargetSettings.ANY_COMPILER)); ActionListener updateCgoListener = event -> { String selected = StringUtil.notNullize(myCgoComboModel.getSelected(), myDefaultCgo); String oldDefault = myDefaultCgo; String os = expandDefault(selected(myOSCombo, myDefaultOSValue), GoUtil.systemOS()); String arch = expandDefault(selected(myArchCombo, myDefaultArchValue), GoUtil.systemArch()); myDefaultCgo = "Default (" + cgo(GoUtil.systemCgo(os, arch)) + ")"; myCgoComboModel.update(ContainerUtil.newArrayList(myDefaultCgo, ENABLED, DISABLED)); myCgoComboModel.setSelectedItem(oldDefault.equals(selected) ? myDefaultCgo : selected); }; myOSCombo.addActionListener(updateCgoListener); myArchCombo.addActionListener(updateCgoListener); } public void initPanel(@NotNull Module module) { if (!module.isDisposed()) { MessageBusConnection connection = module.getMessageBus().connect(this); connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() { @Override public void rootsChanged(ModuleRootEvent event) { initComboValues(module); } }); initComboValues(module); } } private void initComboValues(@NotNull Module module) { if (!module.isDisposed()) { String sdkVersion = GoSdkService.getInstance(module.getProject()).getSdkVersion(module); myDefaultGoVersion = "Project SDK (" + StringUtil.notNullize(sdkVersion, "any") + ")"; //noinspection unchecked myGoVersionCombo.setModel(createModel(GoConstants.KNOWN_VERSIONS, myDefaultGoVersion)); } } @NotNull private String selectedCompiler() { Object item = myCompilerCombo.getSelectedItem(); return item instanceof String ? (String)item : GoBuildTargetSettings.ANY_COMPILER; } @NotNull private String[] selectedCustomTags() { return ArrayUtil.toStringArray(StringUtil.split(myCustomTagsField.getText(), " ")); } @NotNull private ThreeState selectedCgo() { String string = myCgoComboModel.getSelected(); if (ENABLED.equals(string)) { return ThreeState.YES; } if (DISABLED.equals(string)) { return ThreeState.NO; } return ThreeState.UNSURE; } @NotNull private static String selected(@NotNull ComboBox comboBox, @NotNull String defaultValue) { Object item = comboBox.getSelectedItem(); if (item instanceof String) { return defaultValue.equals(item) ? GoBuildTargetSettings.DEFAULT : (String)item; } return GoBuildTargetSettings.DEFAULT; } @NotNull private static String expandDefault(@NotNull String value, @NotNull String defaultValue) { return GoBuildTargetSettings.DEFAULT.equals(value) ? defaultValue : value; } @NotNull private static MutableCollectionComboBoxModel<String> createModel(@NotNull Collection<String> values, @NotNull String defaultValue) { List<String> items = ContainerUtil.newArrayList(defaultValue); items.addAll(ContainerUtil.sorted(values)); return new MutableCollectionComboBoxModel<>(items, defaultValue); } public boolean isModified(@NotNull GoBuildTargetSettings buildTargetSettings) { return !buildTargetSettings.os.equals(selected(myOSCombo, myDefaultOSValue)) || !buildTargetSettings.arch.equals(selected(myArchCombo, myDefaultArchValue)) || !buildTargetSettings.goVersion.equals(selected(myGoVersionCombo, myDefaultGoVersion)) || buildTargetSettings.cgo != selectedCgo() || !buildTargetSettings.compiler.equals(selectedCompiler()) || !Arrays.equals(buildTargetSettings.customFlags, selectedCustomTags()); } public void apply(@NotNull GoBuildTargetSettings buildTargetSettings) { buildTargetSettings.os = selected(myOSCombo, myDefaultOSValue); buildTargetSettings.arch = selected(myArchCombo, myDefaultArchValue); buildTargetSettings.goVersion = selected(myGoVersionCombo, myDefaultGoVersion); buildTargetSettings.compiler = selectedCompiler(); buildTargetSettings.cgo = selectedCgo(); buildTargetSettings.customFlags = selectedCustomTags(); } public void reset(@NotNull GoBuildTargetSettings buildTargetSettings) { myOSCombo.setSelectedItem(expandDefault(buildTargetSettings.os, myDefaultOSValue)); myArchCombo.setSelectedItem(expandDefault(buildTargetSettings.arch, myDefaultArchValue)); myGoVersionCombo.setSelectedItem(expandDefault(buildTargetSettings.goVersion, myDefaultGoVersion)); myCgoCombo.setSelectedItem(expandDefault(cgo(buildTargetSettings.cgo), myDefaultCgo)); myCompilerCombo.setSelectedItem(buildTargetSettings.compiler); myCustomTagsField.setText(StringUtil.join(buildTargetSettings.customFlags, " ")); } @NotNull public JPanel getPanel() { return myPanel; } @Override public void dispose() { UIUtil.dispose(myPanel); UIUtil.dispose(myOSCombo); UIUtil.dispose(myArchCombo); UIUtil.dispose(myGoVersionCombo); UIUtil.dispose(myCompilerCombo); UIUtil.dispose(myCgoCombo); UIUtil.dispose(myCustomTagsField); } @NotNull private static String cgo(@NotNull ThreeState threeState) { if (threeState == ThreeState.YES) { return ENABLED; } if (threeState == ThreeState.NO) { return DISABLED; } return GoBuildTargetSettings.DEFAULT; } private void createUIComponents() { myDescriptionPane = GoUIUtil.createDescriptionPane(); } }