diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form index f3a7c422e5e..9e1eab97a41 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form @@ -21,12 +21,13 @@ - + + @@ -48,11 +49,12 @@ - + + @@ -222,12 +224,13 @@ - + + @@ -280,12 +283,13 @@ - + + diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java index b2dcbf14ee5..252e92d7edf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java @@ -32,6 +32,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.RawCommandLineEditor; import com.intellij.util.text.VersionComparatorUtil; +import com.intellij.util.ui.ThreeStateCheckBox; import kotlin.collections.ArraysKt; import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function1; @@ -76,18 +77,18 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co private final Project project; private final boolean isProjectSettings; private JPanel contentPane; - private JCheckBox generateNoWarningsCheckBox; + private ThreeStateCheckBox generateNoWarningsCheckBox; private RawCommandLineEditor additionalArgsOptionsField; private JLabel additionalArgsLabel; - private JCheckBox generateSourceMapsCheckBox; + private ThreeStateCheckBox generateSourceMapsCheckBox; private TextFieldWithBrowseButton outputPrefixFile; private TextFieldWithBrowseButton outputPostfixFile; private JLabel labelForOutputPrefixFile; private JLabel labelForOutputPostfixFile; private JLabel labelForOutputDirectory; private JTextField outputDirectory; - private JCheckBox copyRuntimeFilesCheckBox; - private JCheckBox keepAliveCheckBox; + private ThreeStateCheckBox copyRuntimeFilesCheckBox; + private ThreeStateCheckBox keepAliveCheckBox; private JCheckBox enablePreciseIncrementalCheckBox; private JComboBox moduleKindComboBox; private JTextField scriptTemplatesField; @@ -110,7 +111,8 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co CompilerSettings compilerSettings, @Nullable KotlinCompilerWorkspaceSettings compilerWorkspaceSettings, @Nullable K2JVMCompilerArguments k2jvmCompilerArguments, - boolean isProjectSettings + boolean isProjectSettings, + boolean isMultiEditor ) { this.project = project; this.commonCompilerArguments = commonCompilerArguments; @@ -154,6 +156,11 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co keepAliveCheckBox.setVisible(false); k2jvmPanel.setVisible(false); } + + generateNoWarningsCheckBox.setThirdStateEnabled(isMultiEditor); + generateSourceMapsCheckBox.setThirdStateEnabled(isMultiEditor); + copyRuntimeFilesCheckBox.setThirdStateEnabled(isMultiEditor); + keepAliveCheckBox.setThirdStateEnabled(isMultiEditor); } @SuppressWarnings("unused") @@ -164,7 +171,8 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co KotlinCompilerSettings.getInstance(project).getSettings(), ServiceManager.getService(project, KotlinCompilerWorkspaceSettings.class), Kotlin2JvmCompilerArgumentsHolder.getInstance(project).getSettings(), - true); + true, + false); } @NotNull @@ -437,6 +445,50 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co return contentPane; } + public ThreeStateCheckBox getGenerateNoWarningsCheckBox() { + return generateNoWarningsCheckBox; + } + + public RawCommandLineEditor getAdditionalArgsOptionsField() { + return additionalArgsOptionsField; + } + + public ThreeStateCheckBox getGenerateSourceMapsCheckBox() { + return generateSourceMapsCheckBox; + } + + public TextFieldWithBrowseButton getOutputPrefixFile() { + return outputPrefixFile; + } + + public TextFieldWithBrowseButton getOutputPostfixFile() { + return outputPostfixFile; + } + + public JTextField getOutputDirectory() { + return outputDirectory; + } + + public ThreeStateCheckBox getCopyRuntimeFilesCheckBox() { + return copyRuntimeFilesCheckBox; + } + + public ThreeStateCheckBox getKeepAliveCheckBox() { + return keepAliveCheckBox; + } + + public JComboBox getModuleKindComboBox() { + return moduleKindComboBox; + } + + public JTextField getScriptTemplatesField() { + return scriptTemplatesField; + } + + public JTextField getScriptTemplatesClasspathField() { + return scriptTemplatesClasspathField; + } + public JComboBox getLanguageVersionComboBox() { return languageVersionComboBox; } @@ -444,4 +496,8 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co public JComboBox getApiVersionComboBox() { return apiVersionComboBox; } + + public JComboBox getCoroutineSupportComboBox() { + return coroutineSupportComboBox; + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt index 3f3cc9483b7..9334cae6f1c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt @@ -19,8 +19,14 @@ package org.jetbrains.kotlin.idea.facet import com.intellij.facet.impl.ui.libraries.DelegatingLibrariesValidatorContext import com.intellij.facet.ui.* import com.intellij.facet.ui.libraries.FrameworkLibraryValidator +import com.intellij.openapi.project.Project import com.intellij.util.ui.FormBuilder +import com.intellij.util.ui.ThreeStateCheckBox import com.intellij.util.ui.UIUtil +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.config.CompilerSettings +import org.jetbrains.kotlin.config.KotlinCompilerInfo import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.TargetPlatformKind import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerConfigurableTab @@ -32,13 +38,73 @@ class KotlinFacetEditorGeneralTab( private val editorContext: FacetEditorContext, validatorsManager: FacetValidatorsManager ) : FacetEditorTab() { + class EditorComponent( + project: Project, + configuration: KotlinFacetConfiguration? + ) : JPanel(BorderLayout()) { + private val isMultiEditor = configuration == null + + private val compilerInfo = configuration?.settings?.compilerInfo + ?: KotlinCompilerInfo() + .apply { + commonCompilerArguments = object : CommonCompilerArguments() {} + k2jsCompilerArguments = K2JSCompilerArguments() + compilerSettings = CompilerSettings() + } + val compilerConfigurable = with(compilerInfo) { + KotlinCompilerConfigurableTab( + project, + commonCompilerArguments, + k2jsCompilerArguments, + compilerSettings, + null, + null, + false, + isMultiEditor + ) + } + + val useProjectSettingsCheckBox = ThreeStateCheckBox("Use project settings").apply { isThirdStateEnabled = isMultiEditor } + + val targetPlatformComboBox = + JComboBox>(TargetPlatformKind.ALL_PLATFORMS.toTypedArray()).apply { + setRenderer(DescriptionListCellRenderer()) + } + + init { + val contentPanel = FormBuilder + .createFormBuilder() + .addComponent(useProjectSettingsCheckBox) + .addLabeledComponent("&Target platform: ", targetPlatformComboBox) + .addComponent(compilerConfigurable.createComponent()!!) + .panel + add(contentPanel, BorderLayout.NORTH) + + useProjectSettingsCheckBox.addActionListener { + updateCompilerConfigurable() + } + + targetPlatformComboBox.addActionListener { + updateCompilerConfigurable() + } + } + + internal fun updateCompilerConfigurable() { + compilerConfigurable.setTargetPlatform(chosenPlatform) + UIUtil.setEnabled(compilerConfigurable.contentPane, !useProjectSettingsCheckBox.isSelected, true) + } + + val chosenPlatform: TargetPlatformKind<*>? + get() = targetPlatformComboBox.selectedItem as TargetPlatformKind<*>? + } + inner class VersionValidator : FacetEditorValidator() { override fun check(): ValidationResult { - val apiLevel = compilerConfigurable.apiVersionComboBox.selectedItem as? LanguageVersion? + val apiLevel = editor.compilerConfigurable.apiVersionComboBox.selectedItem as? LanguageVersion? ?: return ValidationResult.OK - val languageLevel = compilerConfigurable.languageVersionComboBox.selectedItem as? LanguageVersion? + val languageLevel = editor.compilerConfigurable.languageVersionComboBox.selectedItem as? LanguageVersion? ?: return ValidationResult.OK - val targetPlatform = targetPlatformComboBox.selectedItem as TargetPlatformKind<*>? + val targetPlatform = editor.targetPlatformComboBox.selectedItem as TargetPlatformKind<*>? val libraryLevel = getLibraryLanguageLevel(editorContext.module, editorContext.rootModel, targetPlatform) if (languageLevel < apiLevel || libraryLevel < apiLevel) { return ValidationResult("Language version/Runtime version may not be less than API version", null) @@ -47,24 +113,7 @@ class KotlinFacetEditorGeneralTab( } } - private val compilerConfigurable = with(configuration.settings.compilerInfo) { - KotlinCompilerConfigurableTab( - editorContext.project, - commonCompilerArguments, - k2jsCompilerArguments, - compilerSettings, - null, - null, - false - ) - } - - private val useProjectSettingsCheckBox = JCheckBox("Use project settings") - - private val targetPlatformComboBox = - JComboBox>(TargetPlatformKind.ALL_PLATFORMS.toTypedArray()).apply { - setRenderer(DescriptionListCellRenderer()) - } + val editor = EditorComponent(editorContext.project, configuration) private val libraryValidator: FrameworkLibraryValidator private val versionValidator = VersionValidator() @@ -74,56 +123,46 @@ class KotlinFacetEditorGeneralTab( DelegatingLibrariesValidatorContext(editorContext), validatorsManager, "kotlin" - ) { targetPlatformComboBox.selectedItem as TargetPlatformKind<*> } + ) { editor.targetPlatformComboBox.selectedItem as TargetPlatformKind<*> } validatorsManager.registerValidator(libraryValidator) validatorsManager.registerValidator(versionValidator) - useProjectSettingsCheckBox.addActionListener { - updateCompilerConfigurable() - } - - compilerConfigurable.languageVersionComboBox.addActionListener { + editor.compilerConfigurable.languageVersionComboBox.addActionListener { validatorsManager.validate() } - compilerConfigurable.apiVersionComboBox.addActionListener { + editor.compilerConfigurable.apiVersionComboBox.addActionListener { validatorsManager.validate() } - targetPlatformComboBox.addActionListener { + editor.targetPlatformComboBox.addActionListener { validatorsManager.validate() - updateCompilerConfigurable() } - updateCompilerConfigurable() + editor.updateCompilerConfigurable() reset() } - private fun updateCompilerConfigurable() { - compilerConfigurable.setTargetPlatform(chosenPlatform) - UIUtil.setEnabled(compilerConfigurable.contentPane, !useProjectSettingsCheckBox.isSelected, true) - } - override fun isModified(): Boolean { - if (useProjectSettingsCheckBox.isSelected != configuration.settings.useProjectSettings) return true - if (targetPlatformComboBox.selectedItem != configuration.settings.versionInfo.targetPlatformKind) return true - return !useProjectSettingsCheckBox.isSelected && compilerConfigurable.isModified + if (editor.useProjectSettingsCheckBox.isSelected != configuration.settings.useProjectSettings) return true + if (editor.targetPlatformComboBox.selectedItem != configuration.settings.versionInfo.targetPlatformKind) return true + return !editor.useProjectSettingsCheckBox.isSelected && editor.compilerConfigurable.isModified } override fun reset() { - useProjectSettingsCheckBox.isSelected = configuration.settings.useProjectSettings - targetPlatformComboBox.selectedItem = configuration.settings.versionInfo.targetPlatformKind - compilerConfigurable.reset() - updateCompilerConfigurable() + editor.useProjectSettingsCheckBox.isSelected = configuration.settings.useProjectSettings + editor.targetPlatformComboBox.selectedItem = configuration.settings.versionInfo.targetPlatformKind + editor.compilerConfigurable.reset() + editor.updateCompilerConfigurable() } override fun apply() { - compilerConfigurable.apply() + editor.compilerConfigurable.apply() with(configuration.settings) { - useProjectSettings = useProjectSettingsCheckBox.isSelected - versionInfo.targetPlatformKind = targetPlatformComboBox.selectedItem as TargetPlatformKind<*>? + useProjectSettings = editor.useProjectSettingsCheckBox.isSelected + versionInfo.targetPlatformKind = editor.targetPlatformComboBox.selectedItem as TargetPlatformKind<*>? versionInfo.languageLevel = LanguageVersion.fromVersionString(compilerInfo.commonCompilerArguments?.languageVersion) versionInfo.apiLevel = LanguageVersion.fromVersionString(compilerInfo.commonCompilerArguments?.apiVersion) } @@ -135,18 +174,15 @@ class KotlinFacetEditorGeneralTab( val mainPanel = JPanel(BorderLayout()) val contentPanel = FormBuilder .createFormBuilder() - .addComponent(useProjectSettingsCheckBox) - .addLabeledComponent("&Target platform: ", targetPlatformComboBox) - .addComponent(compilerConfigurable.createComponent()!!) + .addComponent(editor.useProjectSettingsCheckBox) + .addLabeledComponent("&Target platform: ", editor.targetPlatformComboBox) + .addComponent(editor.compilerConfigurable.createComponent()!!) .panel mainPanel.add(contentPanel, BorderLayout.NORTH) return mainPanel } override fun disposeUIResources() { - compilerConfigurable.disposeUIResources() + editor.compilerConfigurable.disposeUIResources() } - - val chosenPlatform: TargetPlatformKind<*>? - get() = targetPlatformComboBox.selectedItem as TargetPlatformKind<*>? } diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetType.kt b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetType.kt index f48229db128..928ed01570b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetType.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetType.kt @@ -20,9 +20,11 @@ import com.intellij.facet.Facet import com.intellij.facet.FacetType import com.intellij.facet.FacetTypeId import com.intellij.facet.FacetTypeRegistry +import com.intellij.facet.ui.FacetEditor import com.intellij.openapi.module.JavaModuleType import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleType +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.idea.KotlinIcons import javax.swing.Icon @@ -48,4 +50,7 @@ class KotlinFacetType : FacetType(TYPE_ID configuration: KotlinFacetConfiguration, underlyingFacet: Facet<*>? ) = KotlinFacet(module, name, configuration) + + override fun createMultipleConfigurationsEditor(project: Project, editors: Array) = + MultipleKotlinFacetEditor(project, editors) } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt b/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt new file mode 100644 index 00000000000..f544fc8913f --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.idea.facet + +import com.intellij.facet.ui.FacetEditor +import com.intellij.facet.ui.FacetEditorsFactory +import com.intellij.facet.ui.MultipleFacetSettingsEditor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerConfigurableTab +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance +import javax.swing.JComponent + +class MultipleKotlinFacetEditor( + private val project: Project, + private val editors: Array +) : MultipleFacetSettingsEditor() { + private val helper = FacetEditorsFactory.getInstance().createMultipleFacetEditorHelper() + + private val FacetEditor.tabEditor: KotlinFacetEditorGeneralTab.EditorComponent + get() = editorTabs.firstIsInstance().editor + + private val FacetEditor.compilerConfigurable: KotlinCompilerConfigurableTab + get() = tabEditor.compilerConfigurable + + override fun createComponent(): JComponent? { + return KotlinFacetEditorGeneralTab.EditorComponent(project, null).apply { + helper.bind(useProjectSettingsCheckBox, editors) { it.tabEditor.useProjectSettingsCheckBox } + helper.bind(targetPlatformComboBox, editors) { it.tabEditor.targetPlatformComboBox } + with(compilerConfigurable) { + helper.bind(generateNoWarningsCheckBox, editors) { it.compilerConfigurable.generateNoWarningsCheckBox } + helper.bind(additionalArgsOptionsField.textField, editors) { it.compilerConfigurable.additionalArgsOptionsField.textField } + helper.bind(generateSourceMapsCheckBox, editors) { it.compilerConfigurable.generateSourceMapsCheckBox} + helper.bind(outputPrefixFile.textField, editors) { it.compilerConfigurable.outputPrefixFile.textField} + helper.bind(outputPostfixFile.textField, editors) { it.compilerConfigurable.outputPostfixFile.textField} + helper.bind(outputDirectory, editors) { it.compilerConfigurable.outputDirectory} + helper.bind(copyRuntimeFilesCheckBox, editors) { it.compilerConfigurable.copyRuntimeFilesCheckBox} + helper.bind(keepAliveCheckBox, editors) { it.compilerConfigurable.keepAliveCheckBox} + helper.bind(moduleKindComboBox, editors) { it.compilerConfigurable.moduleKindComboBox} + helper.bind(scriptTemplatesField, editors) { it.compilerConfigurable.scriptTemplatesField} + helper.bind(scriptTemplatesClasspathField, editors) { it.compilerConfigurable.scriptTemplatesClasspathField} + helper.bind(languageVersionComboBox, editors) { it.compilerConfigurable.languageVersionComboBox} + helper.bind(apiVersionComboBox, editors) { it.compilerConfigurable.apiVersionComboBox} + helper.bind(coroutineSupportComboBox, editors) { it.compilerConfigurable.coroutineSupportComboBox} + } + } + } + + override fun disposeUIResources() { + helper.unbind() + } +} \ No newline at end of file