package com.jetbrains.lang.dart.ide.runner.test.ui; import com.intellij.execution.configuration.EnvironmentVariablesComponent; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.JBColor; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.util.ui.UIUtil; import com.jetbrains.lang.dart.DartBundle; import com.jetbrains.lang.dart.ide.runner.server.ui.DartCommandLineConfigurationEditorForm; import com.jetbrains.lang.dart.ide.runner.test.DartTestRunConfiguration; import com.jetbrains.lang.dart.ide.runner.test.DartTestRunnerParameters; import com.jetbrains.lang.dart.util.PubspecYamlUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.DocumentEvent; import static com.jetbrains.lang.dart.ide.runner.test.DartTestRunnerParameters.Scope.*; public class DartTestConfigurationEditorForm extends SettingsEditor<DartTestRunConfiguration> { private JPanel myMainPanel; private JComboBox myScopeCombo; private JLabel myTestFileLabel; private TextFieldWithBrowseButton myFileField; private JLabel myDirLabel; private TextFieldWithBrowseButton myDirField; private JLabel myTestNameLabel; private JTextField myTestNameField; private JLabel myTargetNameLabel; private JTextField myTargetNameField; private JTextField myTestRunnerOptionsField; private EnvironmentVariablesComponent myEnvironmentVariables; public DartTestConfigurationEditorForm(@NotNull final Project project) { DartCommandLineConfigurationEditorForm.initDartFileTextWithBrowse(project, myFileField); myDirField.addBrowseFolderListener(DartBundle.message("choose.dart.directory"), null, project, // Unfortunately, withFileFilter() only works for files, not directories. FileChooserDescriptorFactory.createSingleFolderDescriptor()); myDirField.addActionListener(e -> onTestDirChanged(project)); myScopeCombo.setModel( new DefaultComboBoxModel<>(new DartTestRunnerParameters.Scope[]{FOLDER, FILE, GROUP_OR_TEST_BY_NAME})); myScopeCombo.setRenderer(new ListCellRendererWrapper<DartTestRunnerParameters.Scope>() { @Override public void customize(final JList list, final DartTestRunnerParameters.Scope value, final int index, final boolean selected, final boolean hasFocus) { setText(value.getPresentableName()); } }); myScopeCombo.addActionListener(e -> onScopeChanged()); final DocumentAdapter dirListener = new DocumentAdapter() { @Override protected void textChanged(final DocumentEvent e) { onTestDirChanged(project); } }; myDirField.getTextField().getDocument().addDocumentListener(dirListener); // 'Environment variables' is the widest label, anchored by myTestFileLabel myTestFileLabel.setPreferredSize(myEnvironmentVariables.getLabel().getPreferredSize()); myDirLabel.setPreferredSize(myEnvironmentVariables.getLabel().getPreferredSize()); myEnvironmentVariables.setAnchor(myTestFileLabel); } @Override protected void resetEditorFrom(@NotNull final DartTestRunConfiguration configuration) { final DartTestRunnerParameters parameters = configuration.getRunnerParameters(); myScopeCombo.setSelectedItem(parameters.getScope()); String testPath = FileUtil.toSystemDependentName(StringUtil.notNullize(parameters.getFilePath())); if (parameters.getScope() == FOLDER) { myDirField.setText(testPath); myTargetNameField.setText(parameters.getTargetName()); } else { myFileField.setText(testPath); } myTestNameField.setText( parameters.getScope() == GROUP_OR_TEST_BY_NAME ? StringUtil.notNullize(parameters.getTestName()) : ""); myTestRunnerOptionsField.setText(parameters.getTestRunnerOptions()); myEnvironmentVariables.setEnvs(parameters.getEnvs()); myEnvironmentVariables.setPassParentEnvs(parameters.isIncludeParentEnvs()); onScopeChanged(); } @Override protected void applyEditorTo(@NotNull final DartTestRunConfiguration configuration) throws ConfigurationException { final DartTestRunnerParameters parameters = configuration.getRunnerParameters(); final DartTestRunnerParameters.Scope scope = (DartTestRunnerParameters.Scope)myScopeCombo.getSelectedItem(); parameters.setScope(scope); TextFieldWithBrowseButton pathSource = scope == FOLDER ? myDirField : myFileField; parameters.setFilePath(StringUtil.nullize(FileUtil.toSystemIndependentName(pathSource.getText().trim()))); parameters.setTestName( scope == GROUP_OR_TEST_BY_NAME ? StringUtil.nullize(myTestNameField.getText().trim()) : null); parameters .setTargetName(scope == FOLDER ? StringUtil.nullize(myTargetNameField.getText().trim()) : null); parameters.setTestRunnerOptions(StringUtil.nullize(myTestRunnerOptionsField.getText().trim())); parameters.setEnvs(myEnvironmentVariables.getEnvs()); parameters.setIncludeParentEnvs(myEnvironmentVariables.isPassParentEnvs()); } private void onScopeChanged() { final DartTestRunnerParameters.Scope scope = (DartTestRunnerParameters.Scope)myScopeCombo.getSelectedItem(); myTestNameLabel.setVisible(scope == GROUP_OR_TEST_BY_NAME); myTestNameField.setVisible(scope == GROUP_OR_TEST_BY_NAME); boolean folderMode = scope == FOLDER; boolean projectWithoutPubspec = Registry.is("dart.projects.without.pubspec", false); myFileField.setVisible(!folderMode); myTestFileLabel.setVisible(!folderMode); myDirField.setVisible(folderMode); myDirLabel.setVisible(folderMode); myTargetNameField.setVisible(folderMode && projectWithoutPubspec); myTargetNameLabel.setVisible(folderMode && projectWithoutPubspec); } private void onTestDirChanged(Project project) { if (!isDirApplicable(myDirField.getText(), project)) { myDirField.getTextField().setForeground(JBColor.RED); final String message = DartBundle.message("test.dir.not.in.project"); myDirField.getTextField().setToolTipText(message); } else { myDirField.getTextField().setForeground(UIUtil.getFieldForegroundColor()); myDirField.getTextField().setToolTipText(null); } } @NotNull @Override protected JComponent createEditor() { return myMainPanel; } private static boolean isDirApplicable(@NotNull final String path, @NotNull final Project project) { final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); return file != null && file.isDirectory() && PubspecYamlUtil.findPubspecYamlFile(project, file) != null; } }