package com.google.jstestdriver.idea.execution.settings.ui; import com.google.jstestdriver.idea.execution.JstdRunConfiguration; import com.google.jstestdriver.idea.execution.settings.JstdRunSettings; import com.google.jstestdriver.idea.execution.settings.TestType; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBTabbedPane; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Arrays; import java.util.EnumMap; import java.util.List; import java.util.Map; public class JstdRunConfigurationEditor extends SettingsEditor<JstdRunConfiguration> { private final Map<String, RunSettingsSection> myTabSections; private final JComponent myRootComponent; public JstdRunConfigurationEditor(@NotNull Project project) { myTabSections = ContainerUtil.newLinkedHashMap(); myTabSections.put("Configuration", new RootSection()); myTabSections.put("Server", new JstdRunConfigurationServerSection()); myTabSections.put("Debug", new JstdDebugSection()); myTabSections.put("Coverage", new JstdCoverageSection(project)); myRootComponent = createTabbedPane(project, myTabSections); } @NotNull private static JBTabbedPane createTabbedPane(@NotNull Project project, @NotNull Map<String, RunSettingsSection> tabs) { JBTabbedPane tabbedPane = new JBTabbedPane(); CreationContext content = new CreationContext(project); for (Map.Entry<String, RunSettingsSection> entry : tabs.entrySet()) { JComponent component = entry.getValue().getComponent(content); tabbedPane.addTab(entry.getKey(), component); } tabbedPane.setSelectedIndex(0); return tabbedPane; } @Override protected void resetEditorFrom(@NotNull JstdRunConfiguration runConfiguration) { JstdRunSettings runSettings = runConfiguration.getRunSettings(); for (RunSettingsSection section : myTabSections.values()) { section.resetFrom(runSettings); } } @Override protected void applyEditorTo(@NotNull JstdRunConfiguration runConfiguration) throws ConfigurationException { JstdRunSettings.Builder builder = new JstdRunSettings.Builder(); for (RunSettingsSection section : myTabSections.values()) { section.applyTo(builder); } runConfiguration.setRunSettings(builder.build()); } @NotNull @Override protected JComponent createEditor() { return myRootComponent; } private static class RootSection extends AbstractRunSettingsSection { private JComboBox myTestTypeComboBox; private OneOfRunSettingsSection<TestTypeListItem> myTestTypeContentRunSettingsSection; private Map<TestType, TestTypeListItem> myListItemByTestTypeMap; private final JBLabel myLabel = new JBLabel("Test:"); @NotNull @Override protected JComponent createComponent(@NotNull CreationContext creationContext) { JPanel panel = new JPanel(new GridBagLayout()); myLabel.setHorizontalAlignment(SwingConstants.RIGHT); panel.add(myLabel, new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, UIUtil.DEFAULT_HGAP), 0, 0 )); List<TestTypeListItem> testTypeListItems = createTestTypeListItems(); myTestTypeComboBox = createTestTypeComboBox(testTypeListItems); panel.add(myTestTypeComboBox, new GridBagConstraints( 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0 )); myListItemByTestTypeMap = createListItemByTestTypeMap(testTypeListItems); myTestTypeContentRunSettingsSection = new OneOfRunSettingsSection<>(testTypeListItems); panel.add(myTestTypeContentRunSettingsSection.getComponent(creationContext), new GridBagConstraints( 0, 1, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0 )); setAnchor(myTestTypeContentRunSettingsSection.getAnchor()); return panel; } @Override public void resetFrom(@NotNull JstdRunSettings runSettings) { selectTestType(runSettings.getTestType()); myTestTypeContentRunSettingsSection.resetFrom(runSettings); } @Override public void applyTo(@NotNull JstdRunSettings.Builder runSettingsBuilder) { TestType selectedTestType = getSelectedTestType(); selectTestType(selectedTestType); runSettingsBuilder.setTestType(selectedTestType); myTestTypeContentRunSettingsSection.applyTo(runSettingsBuilder); } private static @NotNull List<TestTypeListItem> createTestTypeListItems() { return Arrays.asList( new TestTypeListItem(TestType.ALL_CONFIGS_IN_DIRECTORY, "All configuration files in directory", new AllInDirectoryRunSettingsSection()), new TestTypeListItem(TestType.CONFIG_FILE, "Configuration file", new ConfigFileRunSettingsSection()), new TestTypeListItem(TestType.JS_FILE, "JavaScript test file", new JsFileRunSettingsSection()), new TestTypeListItem(TestType.TEST_CASE, "Case", new TestCaseRunSettingsSection()), new TestTypeListItem(TestType.TEST_METHOD, "Method", new TestMethodRunSettingsSection()) ); } private static @NotNull Map<TestType, TestTypeListItem> createListItemByTestTypeMap( @NotNull List<TestTypeListItem> testTypeListItems ) { EnumMap<TestType, TestTypeListItem> map = new EnumMap<>(TestType.class); for (TestTypeListItem testTypeListItem : testTypeListItems) { map.put(testTypeListItem.getTestType(), testTypeListItem); } return map; } @NotNull private JComboBox createTestTypeComboBox(@NotNull List<TestTypeListItem> testTypeListItems) { JComboBox comboBox = new ComboBox(testTypeListItems.toArray()); comboBox.setRenderer(new ListCellRendererWrapper<TestTypeListItem>() { @Override public void customize(JList list, TestTypeListItem value, int index, boolean selected, boolean hasFocus) { setText(value.getDisplayName()); } }); comboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { selectTestType(getSelectedTestType()); } }); return comboBox; } private void selectTestType(TestType testType) { TestTypeListItem testTypeListItem = myListItemByTestTypeMap.get(testType); ComboBoxModel comboBoxModel = myTestTypeComboBox.getModel(); if (comboBoxModel.getSelectedItem() != testTypeListItem) { comboBoxModel.setSelectedItem(testTypeListItem); } myTestTypeContentRunSettingsSection.select(testTypeListItem); } private @NotNull TestType getSelectedTestType() { return ((TestTypeListItem) myTestTypeComboBox.getSelectedItem()).getTestType(); } @Override public void setAnchor(@Nullable JComponent anchor) { super.setAnchor(anchor); myTestTypeContentRunSettingsSection.setAnchor(anchor); myLabel.setAnchor(anchor); } } }