2e90fba0ae888274bd2117199643797593be5ad2
[idea/community.git] / plugins / junit / src / com / intellij / execution / junit2 / configuration / JUnitConfigurable.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.execution.junit2.configuration;
18
19 import com.intellij.application.options.ModuleDescriptionsComboBox;
20 import com.intellij.execution.ExecutionBundle;
21 import com.intellij.execution.MethodBrowser;
22 import com.intellij.execution.ShortenCommandLine;
23 import com.intellij.execution.configuration.BrowseModuleValueActionListener;
24 import com.intellij.execution.junit.JUnitConfiguration;
25 import com.intellij.execution.junit.JUnitConfigurationType;
26 import com.intellij.execution.junit.JUnitUtil;
27 import com.intellij.execution.junit.TestClassFilter;
28 import com.intellij.execution.testframework.SourceScope;
29 import com.intellij.execution.testframework.TestSearchScope;
30 import com.intellij.execution.ui.*;
31 import com.intellij.ide.util.ClassFilter;
32 import com.intellij.ide.util.PackageChooserDialog;
33 import com.intellij.openapi.fileChooser.FileChooser;
34 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
35 import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
36 import com.intellij.openapi.fileChooser.FileChooserFactory;
37 import com.intellij.openapi.fileTypes.PlainTextLanguage;
38 import com.intellij.openapi.module.Module;
39 import com.intellij.openapi.options.SettingsEditor;
40 import com.intellij.openapi.project.Project;
41 import com.intellij.openapi.ui.ComponentWithBrowseButton;
42 import com.intellij.openapi.ui.LabeledComponent;
43 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
44 import com.intellij.openapi.ui.ex.MessagesEx;
45 import com.intellij.openapi.util.Condition;
46 import com.intellij.openapi.util.io.FileUtil;
47 import com.intellij.openapi.util.registry.Registry;
48 import com.intellij.openapi.util.text.StringUtil;
49 import com.intellij.openapi.vcs.changes.ChangeListManager;
50 import com.intellij.openapi.vcs.changes.LocalChangeList;
51 import com.intellij.openapi.vfs.VirtualFile;
52 import com.intellij.psi.*;
53 import com.intellij.psi.search.GlobalSearchScope;
54 import com.intellij.rt.execution.junit.RepeatCount;
55 import com.intellij.ui.*;
56 import com.intellij.ui.components.JBLabel;
57 import com.intellij.ui.components.fields.ExpandableTextField;
58 import com.intellij.util.IconUtil;
59 import com.intellij.util.ui.UIUtil;
60 import gnu.trove.TIntArrayList;
61 import org.jetbrains.annotations.NotNull;
62
63 import javax.swing.*;
64 import javax.swing.event.ChangeEvent;
65 import javax.swing.event.ChangeListener;
66 import javax.swing.text.Document;
67 import javax.swing.text.PlainDocument;
68 import java.awt.*;
69 import java.awt.event.ActionEvent;
70 import java.awt.event.ActionListener;
71 import java.util.Arrays;
72 import java.util.List;
73
74 public class JUnitConfigurable<T extends JUnitConfiguration> extends SettingsEditor<T> implements PanelWithAnchor {
75   private static final List<TIntArrayList> ourEnabledFields = Arrays.asList(
76     new TIntArrayList(new int[]{0}),
77     new TIntArrayList(new int[]{1}),
78     new TIntArrayList(new int[]{1, 2}),
79     new TIntArrayList(new int[]{3}),
80     new TIntArrayList(new int[]{4}),
81     new TIntArrayList(new int[]{5}),
82     new TIntArrayList(new int[]{1, 2}),
83     new TIntArrayList(new int[]{6})
84     );
85   private static final String[] FORK_MODE_ALL =
86     {JUnitConfiguration.FORK_NONE, JUnitConfiguration.FORK_METHOD, JUnitConfiguration.FORK_KLASS};
87   private static final String[] FORK_MODE = {JUnitConfiguration.FORK_NONE, JUnitConfiguration.FORK_METHOD};
88   private final ConfigurationModuleSelector myModuleSelector;
89   private final LabeledComponent[] myTestLocations = new LabeledComponent[6];
90   private final JUnitConfigurationModel myModel;
91   private final BrowseModuleValueActionListener[] myBrowsers;
92   private JComponent myPackagePanel;
93   private LabeledComponent<EditorTextFieldWithBrowseButton> myPackage;
94   private LabeledComponent<TextFieldWithBrowseButton> myDir;
95   private LabeledComponent<JPanel> myPattern;
96   private LabeledComponent<EditorTextFieldWithBrowseButton> myClass;
97   private LabeledComponent<EditorTextFieldWithBrowseButton> myMethod;
98   private LabeledComponent<EditorTextFieldWithBrowseButton> myCategory;
99   // Fields
100   private JPanel myWholePanel;
101   private LabeledComponent<ModuleDescriptionsComboBox> myModule;
102   private CommonJavaParametersPanel myCommonJavaParameters;
103   private JRadioButton myWholeProjectScope;
104   private JRadioButton mySingleModuleScope;
105   private JRadioButton myModuleWDScope;
106   private TextFieldWithBrowseButton myPatternTextField;
107   private JrePathEditor myJrePathEditor;
108   private LabeledComponent<ShortenCommandLineModeCombo> myShortenClasspathModeCombo;
109   private JComboBox myForkCb;
110   private JBLabel myTestLabel;
111   private JComboBox myTypeChooser;
112   private JBLabel mySearchForTestsLabel;
113   private JPanel myScopesPanel;
114   private JComboBox myRepeatCb;
115   private JTextField myRepeatCountField;
116   private LabeledComponent<JComboBox<String>> myChangeListLabeledComponent;
117   private LabeledComponent<RawCommandLineEditor> myUniqueIdField;
118   private Project myProject;
119   private JComponent anchor;
120
121   public JUnitConfigurable(final Project project) {
122     myProject = project;
123     myModel = new JUnitConfigurationModel(project);
124     myModuleSelector = new ConfigurationModuleSelector(project, getModulesComponent());
125     myJrePathEditor.setDefaultJreSelector(DefaultJreSelector.fromModuleDependencies(getModulesComponent(), false));
126     myCommonJavaParameters.setModuleContext(myModuleSelector.getModule());
127     myCommonJavaParameters.setHasModuleMacro();
128     myModule.getComponent().addActionListener(new ActionListener() {
129       public void actionPerformed(ActionEvent e) {
130         myCommonJavaParameters.setModuleContext(myModuleSelector.getModule());
131       }
132     });
133     myBrowsers = new BrowseModuleValueActionListener[]{
134       new PackageChooserActionListener(project),
135       new TestClassBrowser(project),
136       new MethodBrowser(project) {
137         protected Condition<PsiMethod> getFilter(PsiClass testClass) {
138           return new JUnitUtil.TestMethodFilter(testClass);
139         }
140
141         @Override
142         protected String getClassName() {
143           return JUnitConfigurable.this.getClassName();
144         }
145
146         @Override
147         protected ConfigurationModuleSelector getModuleSelector() {
148           return myModuleSelector;
149         }
150       },
151       new TestsChooserActionListener(project),
152       new BrowseModuleValueActionListener(project) {
153         @Override
154         protected String showDialog() {
155           final VirtualFile virtualFile =
156             FileChooser.chooseFile(FileChooserDescriptorFactory.createSingleFolderDescriptor(), project, null);
157           if (virtualFile != null) {
158             return FileUtil.toSystemDependentName(virtualFile.getPath());
159           }
160           return null;
161         }
162       },
163       new CategoryBrowser(project),
164       null
165     };
166     // Garbage support
167     final DefaultComboBoxModel aModel = new DefaultComboBoxModel();
168     aModel.addElement(JUnitConfigurationModel.ALL_IN_PACKAGE);
169     aModel.addElement(JUnitConfigurationModel.DIR);
170     aModel.addElement(JUnitConfigurationModel.PATTERN);
171     aModel.addElement(JUnitConfigurationModel.CLASS);
172     aModel.addElement(JUnitConfigurationModel.METHOD);
173     aModel.addElement(JUnitConfigurationModel.CATEGORY);
174     aModel.addElement(JUnitConfigurationModel.UNIQUE_ID);
175     if (Registry.is("testDiscovery.enabled")) {
176       aModel.addElement(JUnitConfigurationModel.BY_SOURCE_POSITION);
177       aModel.addElement(JUnitConfigurationModel.BY_SOURCE_CHANGES);
178     }
179     myTypeChooser.setModel(aModel);
180     myTypeChooser.setRenderer(new ListCellRendererWrapper<Integer>() {
181       @Override
182       public void customize(JList list, Integer value, int index, boolean selected, boolean hasFocus) {
183         switch (value) {
184           case JUnitConfigurationModel.ALL_IN_PACKAGE:
185             setText("All in package");
186             break;
187           case JUnitConfigurationModel.DIR:
188             setText("All in directory");
189             break;
190           case JUnitConfigurationModel.PATTERN:
191             setText("Pattern");
192             break;
193           case JUnitConfigurationModel.CLASS:
194             setText("Class");
195             break;
196           case JUnitConfigurationModel.METHOD:
197             setText("Method");
198             break;
199           case JUnitConfigurationModel.CATEGORY:
200             setText("Category");
201             break;
202           case JUnitConfigurationModel.UNIQUE_ID:
203             setText("UniqueId");
204             break;
205           case JUnitConfigurationModel.BY_SOURCE_POSITION:
206             setText("Through source location");
207             break;
208           case JUnitConfigurationModel.BY_SOURCE_CHANGES:
209             setText("Over changes in sources");
210             break;
211         }
212       }
213     });
214
215     myTestLocations[JUnitConfigurationModel.ALL_IN_PACKAGE] = myPackage;
216     myTestLocations[JUnitConfigurationModel.CLASS] = myClass;
217     myTestLocations[JUnitConfigurationModel.METHOD] = myMethod;
218     myTestLocations[JUnitConfigurationModel.DIR] = myDir;
219     myTestLocations[JUnitConfigurationModel.CATEGORY] = myCategory;
220
221     myRepeatCb.setModel(new DefaultComboBoxModel(RepeatCount.REPEAT_TYPES));
222     myRepeatCb.setSelectedItem(RepeatCount.ONCE);
223     myRepeatCb.addActionListener(new ActionListener() {
224       @Override
225       public void actionPerformed(ActionEvent e) {
226         myRepeatCountField.setEnabled(RepeatCount.N.equals(myRepeatCb.getSelectedItem()));
227       }
228     });
229
230     final JPanel panel = myPattern.getComponent();
231     panel.setLayout(new BorderLayout());
232     myPatternTextField = new TextFieldWithBrowseButton(new ExpandableTextField());
233     myPatternTextField.setButtonIcon(IconUtil.getAddIcon());
234     panel.add(myPatternTextField, BorderLayout.CENTER);
235     myTestLocations[JUnitConfigurationModel.PATTERN] = myPattern;
236
237     final FileChooserDescriptor dirFileChooser = FileChooserDescriptorFactory.createSingleFolderDescriptor();
238     dirFileChooser.setHideIgnored(false);
239     final JTextField textField = myDir.getComponent().getTextField();
240     InsertPathAction.addTo(textField, dirFileChooser);
241     FileChooserFactory.getInstance().installFileCompletion(textField, dirFileChooser, true, null);
242     // Done
243
244     myModel.setListener(this);
245
246     myTypeChooser.addActionListener(new ActionListener() {
247       @Override
248       public void actionPerformed(ActionEvent e) {
249         final Object selectedItem = myTypeChooser.getSelectedItem();
250         myModel.setType((Integer)selectedItem);
251         changePanel();
252       }
253     }
254     );
255
256     myRepeatCb.addActionListener(new ActionListener() {
257       @Override
258       public void actionPerformed(ActionEvent e) {
259         if ((Integer) myTypeChooser.getSelectedItem() == JUnitConfigurationModel.CLASS) {
260           myForkCb.setModel(getForkModelBasedOnRepeat());
261         }
262       }
263     });
264     myModel.setType(JUnitConfigurationModel.CLASS);
265     installDocuments();
266     addRadioButtonsListeners(new JRadioButton[]{myWholeProjectScope, mySingleModuleScope, myModuleWDScope}, null);
267     myWholeProjectScope.addChangeListener(new ChangeListener() {
268       public void stateChanged(final ChangeEvent e) {
269         onScopeChanged();
270       }
271     });
272
273     UIUtil.setEnabled(myCommonJavaParameters.getProgramParametersComponent(), false, true);
274
275     setAnchor(mySearchForTestsLabel);
276     myJrePathEditor.setAnchor(myModule.getLabel());
277     myCommonJavaParameters.setAnchor(myModule.getLabel());
278     myShortenClasspathModeCombo.setAnchor(myModule.getLabel());
279
280     final DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
281     myChangeListLabeledComponent.getComponent().setModel(model);
282     model.addElement("All");
283
284     final List<LocalChangeList> changeLists = ChangeListManager.getInstance(project).getChangeLists();
285     for (LocalChangeList changeList : changeLists) {
286       model.addElement(changeList.getName());
287     }
288
289     myShortenClasspathModeCombo.setComponent(new ShortenCommandLineModeCombo(myProject, myJrePathEditor, myModule.getComponent()));
290   }
291
292   private static void addRadioButtonsListeners(final JRadioButton[] radioButtons, ChangeListener listener) {
293     final ButtonGroup group = new ButtonGroup();
294     for (final JRadioButton radioButton : radioButtons) {
295       radioButton.getModel().addChangeListener(listener);
296       group.add(radioButton);
297     }
298     if (group.getSelection() == null) group.setSelected(radioButtons[0].getModel(), true);
299   }
300
301   public void applyEditorTo(@NotNull final JUnitConfiguration configuration) {
302     configuration.setRepeatMode((String)myRepeatCb.getSelectedItem());
303     try {
304       configuration.setRepeatCount(Integer.parseInt(myRepeatCountField.getText()));
305     }
306     catch (NumberFormatException e) {
307       configuration.setRepeatCount(1);
308     }
309     myModel.apply(getModuleSelector().getModule(), configuration);
310     configuration.getPersistentData().setUniqueIds(myUniqueIdField.getComponent().getText().split(" "));
311     configuration.getPersistentData().setChangeList((String)myChangeListLabeledComponent.getComponent().getSelectedItem());
312     applyHelpersTo(configuration);
313     final JUnitConfiguration.Data data = configuration.getPersistentData();
314     if (myWholeProjectScope.isSelected()) {
315       data.setScope(TestSearchScope.WHOLE_PROJECT);
316     }
317     else if (mySingleModuleScope.isSelected()) {
318       data.setScope(TestSearchScope.SINGLE_MODULE);
319     }
320     else if (myModuleWDScope.isSelected()) {
321       data.setScope(TestSearchScope.MODULE_WITH_DEPENDENCIES);
322     }
323     configuration.setAlternativeJrePath(myJrePathEditor.getJrePathOrName());
324     configuration.setAlternativeJrePathEnabled(myJrePathEditor.isAlternativeJreSelected());
325
326     myCommonJavaParameters.applyTo(configuration);
327     configuration.setForkMode((String)myForkCb.getSelectedItem());
328     configuration.setShortenCommandLine((ShortenCommandLine)myShortenClasspathModeCombo.getComponent().getSelectedItem());
329   }
330
331   public void resetEditorFrom(@NotNull final JUnitConfiguration configuration) {
332     final int count = configuration.getRepeatCount();
333     myRepeatCountField.setText(String.valueOf(count));
334     myRepeatCountField.setEnabled(count > 1);
335     myRepeatCb.setSelectedItem(configuration.getRepeatMode());
336
337     myModel.reset(configuration);
338     myChangeListLabeledComponent.getComponent().setSelectedItem(configuration.getPersistentData().getChangeList());
339     String[] ids = configuration.getPersistentData().getUniqueIds();
340     myUniqueIdField.getComponent().setText(ids != null ? StringUtil.join(ids, " ") : null);
341     myCommonJavaParameters.reset(configuration);
342     getModuleSelector().reset(configuration);
343     final TestSearchScope scope = configuration.getPersistentData().getScope();
344     if (scope == TestSearchScope.SINGLE_MODULE) {
345       mySingleModuleScope.setSelected(true);
346     }
347     else if (scope == TestSearchScope.MODULE_WITH_DEPENDENCIES) {
348       myModuleWDScope.setSelected(true);
349     }
350     else {
351       myWholeProjectScope.setSelected(true);
352     }
353     myJrePathEditor
354       .setPathOrName(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
355     myForkCb.setSelectedItem(configuration.getForkMode());
356     myShortenClasspathModeCombo.getComponent().setSelectedItem(configuration.getShortenCommandLine());
357   }
358
359   private void changePanel () {
360     String selectedItem = (String)myForkCb.getSelectedItem();
361     if (selectedItem == null) {
362       selectedItem = JUnitConfiguration.FORK_NONE;
363     }
364     final Integer selectedType = (Integer)myTypeChooser.getSelectedItem();
365     if (selectedType == JUnitConfigurationModel.ALL_IN_PACKAGE) {
366       myPackagePanel.setVisible(true);
367       myScopesPanel.setVisible(true);
368       myPattern.setVisible(false);
369       myClass.setVisible(false);
370       myCategory.setVisible(false);
371       myUniqueIdField.setVisible(false);
372       myMethod.setVisible(false);
373       myDir.setVisible(false);
374       myChangeListLabeledComponent.setVisible(false);
375       myForkCb.setEnabled(true);
376       myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
377       myForkCb.setSelectedItem(selectedItem);
378     } else if (selectedType == JUnitConfigurationModel.DIR) {
379       myPackagePanel.setVisible(false);
380       myScopesPanel.setVisible(false);
381       myDir.setVisible(true);
382       myPattern.setVisible(false);
383       myClass.setVisible(false);
384       myCategory.setVisible(false);
385       myUniqueIdField.setVisible(false);
386       myChangeListLabeledComponent.setVisible(false);
387       myMethod.setVisible(false);
388       myForkCb.setEnabled(true);
389       myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
390       myForkCb.setSelectedItem(selectedItem);
391     }
392     else if (selectedType == JUnitConfigurationModel.CLASS) {
393       myPackagePanel.setVisible(false);
394       myScopesPanel.setVisible(false);
395       myPattern.setVisible(false);
396       myDir.setVisible(false);
397       myClass.setVisible(true);
398       myCategory.setVisible(false);
399       myUniqueIdField.setVisible(false);
400       myChangeListLabeledComponent.setVisible(false);
401       myMethod.setVisible(false);
402       myForkCb.setEnabled(true);
403       myForkCb.setModel(getForkModelBasedOnRepeat());
404       myForkCb.setSelectedItem(selectedItem != JUnitConfiguration.FORK_KLASS ? selectedItem : JUnitConfiguration.FORK_METHOD);
405     }
406     else if (selectedType == JUnitConfigurationModel.METHOD || selectedType == JUnitConfigurationModel.BY_SOURCE_POSITION){
407       myPackagePanel.setVisible(false);
408       myScopesPanel.setVisible(false);
409       myPattern.setVisible(false);
410       myDir.setVisible(false);
411       myClass.setVisible(true);
412       myCategory.setVisible(false);
413       myUniqueIdField.setVisible(false);
414       myMethod.setVisible(true);
415       myChangeListLabeledComponent.setVisible(false);
416       myForkCb.setEnabled(false);
417       myForkCb.setSelectedItem(JUnitConfiguration.FORK_NONE);
418     } else if (selectedType == JUnitConfigurationModel.CATEGORY) {
419       myPackagePanel.setVisible(false);
420       myScopesPanel.setVisible(true);
421       myDir.setVisible(false);
422       myPattern.setVisible(false);
423       myClass.setVisible(false);
424       myCategory.setVisible(true);
425       myUniqueIdField.setVisible(false);
426       myMethod.setVisible(false);
427       myChangeListLabeledComponent.setVisible(false);
428       myForkCb.setEnabled(true);
429       myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
430       myForkCb.setSelectedItem(selectedItem);
431     }
432     else if (selectedType == JUnitConfigurationModel.BY_SOURCE_CHANGES) {
433       myPackagePanel.setVisible(false);
434       myScopesPanel.setVisible(false);
435       myDir.setVisible(false);
436       myPattern.setVisible(false);
437       myClass.setVisible(false);
438       myCategory.setVisible(false);
439       myUniqueIdField.setVisible(false);
440       myMethod.setVisible(false);
441       myChangeListLabeledComponent.setVisible(true);
442       myForkCb.setEnabled(true);
443       myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
444       myForkCb.setSelectedItem(selectedItem);
445     }
446     else if (selectedType == JUnitConfigurationModel.UNIQUE_ID) {
447       myPackagePanel.setVisible(false);
448       myScopesPanel.setVisible(false);
449       myDir.setVisible(false);
450       myPattern.setVisible(false);
451       myClass.setVisible(false);
452       myCategory.setVisible(false);
453       myUniqueIdField.setVisible(true);
454       myMethod.setVisible(false);
455       myChangeListLabeledComponent.setVisible(false);
456       myForkCb.setEnabled(true);
457       myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
458       myForkCb.setSelectedItem(selectedItem);
459     }
460     else {
461       myPackagePanel.setVisible(false);
462       myScopesPanel.setVisible(true);
463       myPattern.setVisible(true);
464       myDir.setVisible(false);
465       myClass.setVisible(false);
466       myCategory.setVisible(false);
467       myUniqueIdField.setVisible(false);
468       myMethod.setVisible(true);
469       myChangeListLabeledComponent.setVisible(false);
470       myForkCb.setEnabled(true);
471       myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
472       myForkCb.setSelectedItem(selectedItem);
473     }
474   }
475
476   private DefaultComboBoxModel getForkModelBasedOnRepeat() {
477     return new DefaultComboBoxModel(RepeatCount.ONCE.equals(myRepeatCb.getSelectedItem()) ? FORK_MODE : FORK_MODE_ALL);
478   }
479
480   public ModuleDescriptionsComboBox getModulesComponent() {
481     return myModule.getComponent();
482   }
483
484   public ConfigurationModuleSelector getModuleSelector() {
485     return myModuleSelector;
486   }
487
488   private void installDocuments() {
489     for (int i = 0; i < myTestLocations.length; i++) {
490       final LabeledComponent testLocation = getTestLocation(i);
491       final JComponent component = testLocation.getComponent();
492       final ComponentWithBrowseButton field;
493       Object document;
494       if (component instanceof TextFieldWithBrowseButton) {
495         field = (TextFieldWithBrowseButton)component;
496         document = new PlainDocument();
497         ((TextFieldWithBrowseButton)field).getTextField().setDocument((Document)document);
498       } else if (component instanceof EditorTextFieldWithBrowseButton) {
499         field = (ComponentWithBrowseButton)component;
500         document = ((EditorTextField)field.getChildComponent()).getDocument();
501       }
502       else {
503         field = myPatternTextField;
504         document = new PlainDocument();
505         ((TextFieldWithBrowseButton)field).getTextField().setDocument((Document)document);
506         
507       }
508       myBrowsers[i].setField(field);
509       if (myBrowsers[i] instanceof MethodBrowser) {
510         final EditorTextField childComponent = (EditorTextField)field.getChildComponent();
511         ((MethodBrowser)myBrowsers[i]).installCompletion(childComponent);
512         document = childComponent.getDocument();
513       }
514       myModel.setJUnitDocument(i, document);
515     }
516   }
517
518   public LabeledComponent getTestLocation(final int index) {
519     return myTestLocations[index];
520   }
521
522   private void createUIComponents() {
523     myPackage = new LabeledComponent<>();
524     myPackage.setComponent(new EditorTextFieldWithBrowseButton(myProject, false));
525
526     myClass = new LabeledComponent<>();
527     final TestClassBrowser classBrowser = new TestClassBrowser(myProject);
528     myClass.setComponent(new EditorTextFieldWithBrowseButton(myProject, true, new JavaCodeFragment.VisibilityChecker() {
529       @Override
530       public Visibility isDeclarationVisible(PsiElement declaration, PsiElement place) {
531         try {
532           if (declaration instanceof PsiClass && (classBrowser.getFilter().isAccepted(((PsiClass)declaration)) || classBrowser.findClass(((PsiClass)declaration).getQualifiedName()) != null && place.getParent() != null)) {
533             return Visibility.VISIBLE;
534           }
535         }
536         catch (ClassBrowser.NoFilterException e) {
537           return Visibility.NOT_VISIBLE;
538         }
539         return Visibility.NOT_VISIBLE;
540       }
541     }));
542
543     myCategory = new LabeledComponent<>();
544     myCategory.setComponent(new EditorTextFieldWithBrowseButton(myProject, true, new JavaCodeFragment.VisibilityChecker() {
545       @Override
546       public Visibility isDeclarationVisible(PsiElement declaration, PsiElement place) {
547         if (declaration instanceof PsiClass) {
548           return Visibility.VISIBLE;
549         }
550         return Visibility.NOT_VISIBLE;
551       }
552     }));
553
554     myMethod = new LabeledComponent<>();
555     final EditorTextFieldWithBrowseButton textFieldWithBrowseButton = new EditorTextFieldWithBrowseButton(myProject, true,
556                                                                                                           JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE,
557                                                                                                           PlainTextLanguage.INSTANCE.getAssociatedFileType());
558     myMethod.setComponent(textFieldWithBrowseButton);
559
560     myShortenClasspathModeCombo = new LabeledComponent<>();
561   }
562
563   @Override
564   public JComponent getAnchor() {
565     return anchor;
566   }
567
568   @Override
569   public void setAnchor(JComponent anchor) {
570     this.anchor = anchor;
571     mySearchForTestsLabel.setAnchor(anchor);
572     myTestLabel.setAnchor(anchor);
573     myClass.setAnchor(anchor);
574     myDir.setAnchor(anchor);
575     myMethod.setAnchor(anchor);
576     myPattern.setAnchor(anchor);
577     myPackage.setAnchor(anchor);
578     myCategory.setAnchor(anchor);
579     myUniqueIdField.setAnchor(anchor);
580     myChangeListLabeledComponent.setAnchor(anchor);
581   }
582
583   public void onTypeChanged(final int newType) {
584     myTypeChooser.setSelectedItem(newType);
585     final TIntArrayList enabledFields = ourEnabledFields.get(newType);
586     for (int i = 0; i < myTestLocations.length; i++)
587       getTestLocation(i).setEnabled(enabledFields.contains(i));
588     /*if (newType == JUnitConfigurationModel.PATTERN) {
589       myModule.setEnabled(false);
590     } else */if (newType != JUnitConfigurationModel.ALL_IN_PACKAGE &&
591                  newType != JUnitConfigurationModel.PATTERN &&
592                  newType != JUnitConfigurationModel.CATEGORY &&
593                  newType != JUnitConfigurationModel.UNIQUE_ID) {
594       myModule.setEnabled(true);
595     }
596     else {
597       onScopeChanged();
598     }
599   }
600
601   private void onScopeChanged() {
602     final Integer selectedItem = (Integer)myTypeChooser.getSelectedItem();
603     final boolean allInPackageAllInProject = (selectedItem == JUnitConfigurationModel.ALL_IN_PACKAGE ||
604                                               selectedItem == JUnitConfigurationModel.PATTERN ||
605                                               selectedItem == JUnitConfigurationModel.CATEGORY ||
606                                               selectedItem == JUnitConfigurationModel.UNIQUE_ID ) && myWholeProjectScope.isSelected();
607     myModule.setEnabled(!allInPackageAllInProject);
608     if (allInPackageAllInProject) {
609       myModule.getComponent().setSelectedItem(null);
610     }
611   }
612
613   private String getClassName() {
614     return ((LabeledComponent<EditorTextFieldWithBrowseButton>)getTestLocation(JUnitConfigurationModel.CLASS)).getComponent().getText();
615   }
616
617   private void setPackage(final PsiPackage aPackage) {
618     if (aPackage == null) return;
619     ((LabeledComponent<EditorTextFieldWithBrowseButton>)getTestLocation(JUnitConfigurationModel.ALL_IN_PACKAGE)).getComponent()
620       .setText(aPackage.getQualifiedName());
621   }
622
623   @NotNull
624   public JComponent createEditor() {
625     return myWholePanel;
626   }
627
628   private void applyHelpersTo(final JUnitConfiguration currentState) {
629     myCommonJavaParameters.applyTo(currentState);
630     getModuleSelector().applyTo(currentState);
631   }
632
633   private static class PackageChooserActionListener extends BrowseModuleValueActionListener {
634     public PackageChooserActionListener(final Project project) {
635       super(project);
636     }
637
638     protected String showDialog() {
639       final PackageChooserDialog dialog = new PackageChooserDialog(ExecutionBundle.message("choose.package.dialog.title"), getProject());
640       dialog.show();
641       final PsiPackage aPackage = dialog.getSelectedPackage();
642       return aPackage != null ? aPackage.getQualifiedName() : null;
643     }
644   }
645
646   private class TestsChooserActionListener extends TestClassBrowser {
647     public TestsChooserActionListener(final Project project) {
648       super(project);
649     }
650
651     @Override
652     protected void onClassChoosen(PsiClass psiClass) {
653       final JTextField textField = myPatternTextField.getTextField();
654       final String text = textField.getText();
655       textField.setText(text + (text.length() > 0 ? "||" : "") + psiClass.getQualifiedName());
656     }
657
658     @Override
659     protected ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException {
660       try {
661         return TestClassFilter.create(SourceScope.wholeProject(getProject()), null);
662       }
663       catch (JUnitUtil.NoJUnitException ignore) {
664         throw new NoFilterException(new MessagesEx.MessageInfo(getProject(),
665                                                                ignore.getMessage(),
666                                                                ExecutionBundle.message("cannot.browse.test.inheritors.dialog.title")));
667       }
668     }
669
670     @Override
671     public void actionPerformed(ActionEvent e) {
672       showDialog();
673     }
674   }
675
676   private class TestClassBrowser extends ClassBrowser {
677     public TestClassBrowser(final Project project) {
678       super(project, ExecutionBundle.message("choose.test.class.dialog.title"));
679     }
680
681     protected void onClassChoosen(final PsiClass psiClass) {
682       setPackage(JUnitUtil.getContainingPackage(psiClass));
683     }
684
685     protected PsiClass findClass(final String className) {
686       return getModuleSelector().findClass(className);
687     }
688
689     protected ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException {
690       final ConfigurationModuleSelector moduleSelector = getModuleSelector();
691       final Module module = moduleSelector.getModule();
692       if (module == null) {
693         throw NoFilterException.moduleDoesntExist(moduleSelector);
694       }
695       final ClassFilter.ClassFilterWithScope classFilter;
696       try {
697         final JUnitConfiguration configurationCopy =
698           new JUnitConfiguration(ExecutionBundle.message("default.junit.configuration.name"), getProject(),
699                                  JUnitConfigurationType.getInstance().getConfigurationFactories()[0]);
700         applyEditorTo(configurationCopy);
701         classFilter = TestClassFilter
702           .create(SourceScope.modulesWithDependencies(configurationCopy.getModules()), configurationCopy.getConfigurationModule().getModule());
703       }
704       catch (JUnitUtil.NoJUnitException e) {
705         throw NoFilterException.noJUnitInModule(module);
706       }
707       return classFilter;
708     }
709   }
710
711   private class CategoryBrowser extends ClassBrowser {
712     public CategoryBrowser(Project project) {
713       super(project, "Category Interface");
714     }
715
716     protected PsiClass findClass(final String className) {
717       return myModuleSelector.findClass(className);
718     }
719
720     protected ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException {
721       final Module module = myModuleSelector.getModule();
722       final GlobalSearchScope scope;
723       if (module == null) {
724         scope = GlobalSearchScope.allScope(myProject);
725       }
726       else {
727         scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
728       }
729       return new ClassFilter.ClassFilterWithScope() {
730         public GlobalSearchScope getScope() {
731           return scope;
732         }
733
734         public boolean isAccepted(final PsiClass aClass) {
735           return true;
736         }
737       };
738     }
739
740     @Override
741     protected void onClassChoosen(PsiClass psiClass) {
742       ((LabeledComponent<EditorTextFieldWithBrowseButton>)getTestLocation(JUnitConfigurationModel.CATEGORY)).getComponent()
743         .setText(psiClass.getQualifiedName());
744     }
745   }
746 }