SSR: don't enable "apply constraint within type hierarchy" when not searching java
[idea/community.git] / platform / structuralsearch / source / com / intellij / structuralsearch / plugin / ui / EditVarConstraintsDialog.java
1 package com.intellij.structuralsearch.plugin.ui;
2
3 import com.intellij.codeInsight.template.impl.Variable;
4 import com.intellij.find.impl.RegExHelpPopup;
5 import com.intellij.ide.highlighter.HighlighterFactory;
6 import com.intellij.openapi.application.ApplicationManager;
7 import com.intellij.openapi.diagnostic.Logger;
8 import com.intellij.openapi.editor.Document;
9 import com.intellij.openapi.editor.Editor;
10 import com.intellij.openapi.editor.EditorFactory;
11 import com.intellij.openapi.editor.EditorSettings;
12 import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
13 import com.intellij.openapi.editor.event.DocumentAdapter;
14 import com.intellij.openapi.editor.event.DocumentEvent;
15 import com.intellij.openapi.editor.ex.EditorEx;
16 import com.intellij.openapi.fileTypes.FileType;
17 import com.intellij.openapi.fileTypes.FileTypeManager;
18 import com.intellij.openapi.fileTypes.FileTypes;
19 import com.intellij.openapi.fileTypes.StdFileTypes;
20 import com.intellij.openapi.help.HelpManager;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.openapi.ui.ComponentWithBrowseButton;
23 import com.intellij.openapi.ui.DialogWrapper;
24 import com.intellij.openapi.ui.Messages;
25 import com.intellij.openapi.util.text.StringUtil;
26 import com.intellij.psi.PsiDocumentManager;
27 import com.intellij.psi.PsiFile;
28 import com.intellij.psi.PsiFileFactory;
29 import com.intellij.structuralsearch.*;
30 import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
31 import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
32 import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
33 import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
34 import com.intellij.ui.ComboboxWithBrowseButton;
35 import com.intellij.ui.EditorTextField;
36 import com.intellij.util.containers.ContainerUtil;
37 import org.jetbrains.annotations.NonNls;
38 import org.jetbrains.annotations.NotNull;
39
40 import javax.swing.*;
41 import javax.swing.event.ChangeEvent;
42 import javax.swing.event.ChangeListener;
43 import javax.swing.event.ListSelectionEvent;
44 import javax.swing.event.ListSelectionListener;
45 import java.awt.*;
46 import java.awt.event.ActionEvent;
47 import java.awt.event.ActionListener;
48 import java.util.Collection;
49 import java.util.List;
50 import java.util.regex.Pattern;
51 import java.util.regex.PatternSyntaxException;
52
53 /**
54  * @author Maxim.Mossienko
55  * Date: Mar 25, 2004
56  * Time: 1:52:18 PM
57  */
58 class EditVarConstraintsDialog extends DialogWrapper {
59   private static final Logger LOG = Logger.getInstance("#com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog");
60
61   private JTextField maxoccurs;
62   private JCheckBox applyWithinTypeHierarchy;
63   private JCheckBox notRegexp;
64   private EditorTextField regexp;
65   private JTextField minoccurs;
66   private JPanel mainForm;
67   private JCheckBox notWrite;
68   private JCheckBox notRead;
69   private JCheckBox write;
70   private JCheckBox read;
71   private JList parameterList;
72   private JCheckBox partOfSearchResults;
73   private JCheckBox notExprType;
74   private EditorTextField regexprForExprType;
75   private final SearchModel model;
76   private JCheckBox exprTypeWithinHierarchy;
77
78   private final List<Variable> variables;
79   private Variable current;
80   private JCheckBox wholeWordsOnly;
81   private JCheckBox formalArgTypeWithinHierarchy;
82   private JCheckBox invertFormalArgType;
83   private EditorTextField formalArgType;
84   private ComponentWithBrowseButton<EditorTextField> customScriptCode;
85   private JCheckBox maxoccursUnlimited;
86
87   private ComboboxWithBrowseButton withinCombo;
88   private JPanel containedInConstraints;
89   private JCheckBox invertWithinIn;
90   private JPanel expressionConstraints;
91   private JPanel occurencePanel;
92   private JPanel textConstraintsPanel;
93   private JLabel myRegExHelpLabel;
94
95   private static Project myProject;
96
97   EditVarConstraintsDialog(final Project project, SearchModel _model, List<Variable> _variables, final FileType fileType) {
98     super(project, false);
99
100     variables = _variables;
101     model = _model;
102
103     setTitle(SSRBundle.message("editvarcontraints.edit.variables"));
104
105     regexp.getDocument().addDocumentListener(new MyDocumentListener(notRegexp, wholeWordsOnly));
106     regexp.getDocument().addDocumentListener(new DocumentAdapter() {
107       @Override
108       public void documentChanged(DocumentEvent e) {
109         applyWithinTypeHierarchy.setEnabled(e.getDocument().getTextLength() > 0 && fileType == StdFileTypes.JAVA);
110       }
111     });
112     read.addChangeListener(new MyChangeListener(notRead, false));
113     write.addChangeListener(new MyChangeListener(notWrite, false));
114     regexprForExprType.getDocument().addDocumentListener(new MyDocumentListener(exprTypeWithinHierarchy, notExprType));
115     formalArgType.getDocument().addDocumentListener(new MyDocumentListener(formalArgTypeWithinHierarchy, invertFormalArgType));
116
117     containedInConstraints.setVisible(false);
118     withinCombo.getComboBox().setEditable(true);
119
120     withinCombo.getButton().addActionListener(new ActionListener() {
121       public void actionPerformed(@NotNull final ActionEvent e) {
122         final SelectTemplateDialog dialog = new SelectTemplateDialog(project, false, false);
123         dialog.show();
124         if (dialog.getExitCode() == OK_EXIT_CODE) {
125           final Configuration[] selectedConfigurations = dialog.getSelectedConfigurations();
126           if (selectedConfigurations.length == 1) {
127             withinCombo.getComboBox().getEditor().setItem(selectedConfigurations[0].getMatchOptions().getSearchPattern()); // TODO:
128           }
129         }
130       }
131     });
132
133     boolean hasContextVar = false;
134     for(Variable var:variables) {
135       if (Configuration.CONTEXT_VAR_NAME.equals(var.getName())) {
136         hasContextVar = true; break;
137       }
138     }
139
140     if (!hasContextVar) {
141       variables.add(new Variable(Configuration.CONTEXT_VAR_NAME, "", "", true));
142     }
143
144     if (fileType == StdFileTypes.JAVA) {
145
146       formalArgTypeWithinHierarchy.setEnabled(true);
147       invertFormalArgType.setEnabled(true);
148       formalArgType.setEnabled(true);
149
150       exprTypeWithinHierarchy.setEnabled(true);
151       notExprType.setEnabled(true);
152       regexprForExprType.setEnabled(true);
153
154       read.setEnabled(true);
155       notRead.setEnabled(false);
156       write.setEnabled(true);
157       notWrite.setEnabled(false);
158
159       applyWithinTypeHierarchy.setEnabled(true);
160     } else {
161       formalArgTypeWithinHierarchy.setEnabled(false);
162       invertFormalArgType.setEnabled(false);
163       formalArgType.setEnabled(false);
164
165       exprTypeWithinHierarchy.setEnabled(false);
166       notExprType.setEnabled(false);
167       regexprForExprType.setEnabled(false);
168
169       read.setEnabled(false);
170       notRead.setEnabled(false);
171       write.setEnabled(false);
172       notWrite.setEnabled(false);
173
174       applyWithinTypeHierarchy.setEnabled(false);
175     }
176
177     parameterList.setModel(
178       new AbstractListModel() {
179         public Object getElementAt(int index) {
180           return variables.get(index);
181         }
182
183         public int getSize() {
184           return variables.size();
185         }
186       }
187     );
188
189     parameterList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
190
191     parameterList.getSelectionModel().addListSelectionListener(
192       new ListSelectionListener() {
193         boolean rollingBackSelection;
194
195         public void valueChanged(@NotNull ListSelectionEvent e) {
196           if (e.getValueIsAdjusting()) return;
197           if (rollingBackSelection) {
198             rollingBackSelection=false;
199             return;
200           }
201           final Variable var = variables.get(parameterList.getSelectedIndex());
202           if (validateParameters()) {
203             if (current!=null) copyValuesFromUI(current);
204             ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { copyValuesToUI(var); }});
205             current = var;
206           } else {
207             rollingBackSelection = true;
208             parameterList.setSelectedIndex(e.getFirstIndex()==parameterList.getSelectedIndex()?e.getLastIndex():e.getFirstIndex());
209           }
210         }
211       }
212     );
213
214     parameterList.setCellRenderer(
215       new DefaultListCellRenderer() {
216         public Component getListCellRendererComponent(@NotNull JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
217           String name = ((Variable)value).getName();
218           if (Configuration.CONTEXT_VAR_NAME.equals(name)) name = SSRBundle.message("complete.match.variable.name");
219           if (isReplacementVariable(name)) {
220             name = stripReplacementVarDecoration(name);
221           }
222           return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
223         }
224       }
225     );
226
227     maxoccursUnlimited.addChangeListener(new MyChangeListener(maxoccurs, true));
228
229     customScriptCode.getButton().addActionListener(new ActionListener() {
230       public void actionPerformed(@NotNull final ActionEvent e) {
231         final List<String> variableNames = ContainerUtil.newArrayList(model.getConfig().getMatchOptions().getVariableConstraintNames());
232         variableNames.remove(current.getName());
233         variableNames.remove(CompiledPattern.ALL_CLASS_UNMATCHED_CONTENT_VAR_ARTIFICIAL_NAME);
234         final EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText(), variableNames);
235         dialog.show();
236         if (dialog.getExitCode() == OK_EXIT_CODE) {
237           customScriptCode.getChildComponent().setText(dialog.getScriptText());
238         }
239       }
240     });
241     init();
242
243     if (variables.size() > 0) parameterList.setSelectedIndex(0);
244   }
245
246   private static String stripReplacementVarDecoration(String name) {
247     name = name.substring(0, name.length() - ReplaceConfiguration.REPLACEMENT_VARIABLE_SUFFIX.length());
248     return name;
249   }
250
251   private static boolean isReplacementVariable(String name) {
252     return name.endsWith(ReplaceConfiguration.REPLACEMENT_VARIABLE_SUFFIX);
253   }
254
255   private boolean validateParameters() {
256     return validateRegExp(regexp) && validateRegExp(regexprForExprType) &&
257            validateIntOccurence(minoccurs) &&
258            validateScript(customScriptCode.getChildComponent()) &&
259            (maxoccursUnlimited.isSelected() || validateIntOccurence(maxoccurs));
260   }
261
262   protected JComponent createCenterPanel() {
263     return mainForm;
264   }
265
266   protected void doOKAction() {
267     if(validateParameters()) {
268       if (current!=null) copyValuesFromUI(current);
269       super.doOKAction();
270     }
271   }
272
273   void copyValuesFromUI(Variable var) {
274     String varName = var.getName();
275     Configuration configuration = model.getConfig();
276
277     if (isReplacementVariable(varName)) {
278       saveScriptInfo(getOrAddReplacementVariableDefinition(varName, configuration));
279       return;
280     }
281
282     MatchVariableConstraint varInfo = getOrAddVariableConstraint(varName, configuration);
283
284     varInfo.setInvertReadAccess(notRead.isSelected());
285     varInfo.setReadAccess(read.isSelected());
286     varInfo.setInvertWriteAccess(notWrite.isSelected());
287     varInfo.setWriteAccess(write.isSelected());
288     varInfo.setRegExp(regexp.getDocument().getText());
289     varInfo.setInvertRegExp(notRegexp.isSelected());
290
291     int minCount = Integer.parseInt( minoccurs.getText() );
292     varInfo.setMinCount(minCount);
293
294     int maxCount;
295     if (maxoccursUnlimited.isSelected()) maxCount = Integer.MAX_VALUE;
296     else maxCount = Integer.parseInt( maxoccurs.getText() );
297
298     varInfo.setMaxCount(maxCount);
299     varInfo.setWithinHierarchy(applyWithinTypeHierarchy.isSelected());
300     varInfo.setInvertRegExp(notRegexp.isSelected());
301
302     final boolean target = partOfSearchResults.isSelected();
303     if (target) {
304       final MatchOptions matchOptions = configuration.getMatchOptions();
305       for (String name : matchOptions.getVariableConstraintNames()) {
306         if (!name.equals(varName)) {
307           matchOptions.getVariableConstraint(name).setPartOfSearchResults(false);
308         }
309       }
310     }
311     varInfo.setPartOfSearchResults(target);
312
313     varInfo.setInvertExprType(notExprType.isSelected());
314     varInfo.setNameOfExprType(regexprForExprType.getDocument().getText());
315     varInfo.setExprTypeWithinHierarchy(exprTypeWithinHierarchy.isSelected());
316     varInfo.setWholeWordsOnly(wholeWordsOnly.isSelected());
317     varInfo.setInvertFormalType(invertFormalArgType.isSelected());
318     varInfo.setFormalArgTypeWithinHierarchy(formalArgTypeWithinHierarchy.isSelected());
319     varInfo.setNameOfFormalArgType(formalArgType.getDocument().getText());
320     saveScriptInfo(varInfo);
321
322     final String withinConstraint = (String)withinCombo.getComboBox().getEditor().getItem();
323     varInfo.setWithinConstraint(withinConstraint.length() > 0 ? "\"" + withinConstraint +"\"":"");
324     varInfo.setInvertWithinConstraint(invertWithinIn.isSelected());
325   }
326
327   private static MatchVariableConstraint getOrAddVariableConstraint(String varName, Configuration configuration) {
328     MatchVariableConstraint varInfo = configuration.getMatchOptions().getVariableConstraint(varName);
329
330     if (varInfo == null) {
331       varInfo = new MatchVariableConstraint();
332       varInfo.setName(varName);
333       configuration.getMatchOptions().addVariableConstraint(varInfo);
334     }
335     return varInfo;
336   }
337
338   private static ReplacementVariableDefinition getOrAddReplacementVariableDefinition(String varName, Configuration configuration) {
339     ReplaceOptions replaceOptions = ((ReplaceConfiguration)configuration).getOptions();
340     String realVariableName = stripReplacementVarDecoration(varName);
341     ReplacementVariableDefinition variableDefinition = replaceOptions.getVariableDefinition(realVariableName);
342
343     if (variableDefinition == null) {
344       variableDefinition = new ReplacementVariableDefinition();
345       variableDefinition.setName(realVariableName);
346       replaceOptions.addVariableDefinition(variableDefinition);
347     }
348     return variableDefinition;
349   }
350
351   private void saveScriptInfo(NamedScriptableDefinition varInfo) {
352     varInfo.setScriptCodeConstraint("\"" + customScriptCode.getChildComponent().getText() + "\"");
353   }
354
355   private void copyValuesToUI(Variable var) {
356     Configuration configuration = model.getConfig();
357     String varName = var.getName();
358
359     if (isReplacementVariable(varName)) {
360       ReplacementVariableDefinition definition = ((ReplaceConfiguration)configuration).getOptions().getVariableDefinition(
361         stripReplacementVarDecoration(varName)
362       );
363
364       restoreScriptCode(definition);
365       setSearchConstraintsVisible(false);
366       return;
367     } else {
368       setSearchConstraintsVisible(true);
369     }
370
371     final MatchOptions matchOptions = configuration.getMatchOptions();
372     final MatchVariableConstraint varInfo = matchOptions.getVariableConstraint(varName);
373
374     if (varInfo == null) {
375       notRead.setSelected(false);
376       notRegexp.setSelected(false);
377       read.setSelected(false);
378       notWrite.setSelected(false);
379       write.setSelected(false);
380       regexp.getDocument().setText("");
381
382       minoccurs.setText("1");
383       maxoccurs.setText("1");
384       maxoccursUnlimited.setSelected(false);
385       applyWithinTypeHierarchy.setSelected(false);
386       partOfSearchResults.setSelected(isTarget(varName, matchOptions));
387
388       regexprForExprType.getDocument().setText("");
389       notExprType.setSelected(false);
390       exprTypeWithinHierarchy.setSelected(false);
391       wholeWordsOnly.setSelected(false);
392
393       invertFormalArgType.setSelected(false);
394       formalArgTypeWithinHierarchy.setSelected(false);
395       formalArgType.getDocument().setText("");
396       customScriptCode.getChildComponent().setText("");
397
398       withinCombo.getComboBox().getEditor().setItem("");
399       invertWithinIn.setSelected(false);
400     } else {
401       notRead.setSelected(varInfo.isInvertReadAccess());
402       read.setSelected(varInfo.isReadAccess());
403       notWrite.setSelected(varInfo.isInvertWriteAccess());
404       write.setSelected(varInfo.isWriteAccess());
405       
406       applyWithinTypeHierarchy.setSelected(varInfo.isWithinHierarchy());
407       regexp.getDocument().setText(varInfo.getRegExp());
408       //doProcessing(applyWithinTypeHierarchy,regexp);
409       
410       notRegexp.setSelected(varInfo.isInvertRegExp());
411       minoccurs.setText(Integer.toString(varInfo.getMinCount()));
412
413       if(varInfo.getMaxCount() == Integer.MAX_VALUE) {
414         maxoccursUnlimited.setSelected(true);
415         maxoccurs.setText("");
416       } else {
417         maxoccursUnlimited.setSelected(false);
418         maxoccurs.setText(Integer.toString(varInfo.getMaxCount()));
419       }
420
421       partOfSearchResults.setSelected(isTarget(varName, matchOptions));
422
423       exprTypeWithinHierarchy.setSelected(varInfo.isExprTypeWithinHierarchy());
424       regexprForExprType.getDocument().setText(varInfo.getNameOfExprType());
425
426       notExprType.setSelected( varInfo.isInvertExprType() );
427       wholeWordsOnly.setSelected( varInfo.isWholeWordsOnly() );
428
429       invertFormalArgType.setSelected( varInfo.isInvertFormalType() );
430       formalArgTypeWithinHierarchy.setSelected(varInfo.isFormalArgTypeWithinHierarchy());
431       formalArgType.getDocument().setText(varInfo.getNameOfFormalArgType());
432       restoreScriptCode(varInfo);
433
434       withinCombo.getComboBox().getEditor().setItem(StringUtil.stripQuotesAroundValue(varInfo.getWithinConstraint()));
435       invertWithinIn.setSelected(varInfo.isInvertWithinConstraint());
436     }
437
438     final boolean contextVar = Configuration.CONTEXT_VAR_NAME.equals(var.getName());
439     containedInConstraints.setVisible(contextVar);
440     textConstraintsPanel.setVisible(!contextVar);
441     expressionConstraints.setVisible(!contextVar);
442     partOfSearchResults.setEnabled(!contextVar);
443     occurencePanel.setVisible(!contextVar);
444   }
445
446   private static boolean isTarget(String varName, MatchOptions matchOptions) {
447     if (Configuration.CONTEXT_VAR_NAME.equals(varName)) {
448       // Complete Match is default target
449       for (String name : matchOptions.getVariableConstraintNames()) {
450         if (!name.equals(Configuration.CONTEXT_VAR_NAME)) {
451           if (matchOptions.getVariableConstraint(name).isPartOfSearchResults()) {
452             return false;
453           }
454         }
455       }
456       return true;
457     }
458     final MatchVariableConstraint constraint = matchOptions.getVariableConstraint(varName);
459     if (constraint == null) {
460       return false;
461     }
462     return constraint.isPartOfSearchResults();
463   }
464
465   private void setSearchConstraintsVisible(boolean b) {
466     textConstraintsPanel.setVisible(b);
467     occurencePanel.setVisible(b);
468     expressionConstraints.setVisible(b);
469     partOfSearchResults.setVisible(b);
470     containedInConstraints.setVisible(b);
471   }
472
473   private void restoreScriptCode(NamedScriptableDefinition varInfo) {
474     customScriptCode.getChildComponent().setText(
475       varInfo != null ? StringUtil.stripQuotesAroundValue(varInfo.getScriptCodeConstraint()) : "");
476   }
477
478   protected String getDimensionServiceKey() {
479     return "#com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog";
480   }
481
482   private static boolean validateRegExp(EditorTextField field) {
483     try {
484       final String s = field.getDocument().getText();
485       if (s.length() > 0) {
486         Pattern.compile(s);
487       }
488     } catch(PatternSyntaxException ex) {
489       Messages.showErrorDialog(SSRBundle.message("invalid.regular.expression"), SSRBundle.message("invalid.regular.expression"));
490       field.requestFocus();
491       return false;
492     }
493     return true;
494   }
495
496   private static boolean validateScript(EditorTextField field) {
497     final String text = field.getText();
498
499     if (text.length() > 0) {
500       final String message = ScriptSupport.checkValidScript(text);
501
502       if (message != null) {
503         Messages.showErrorDialog(message, SSRBundle.message("invalid.groovy.script"));
504         field.requestFocus();
505         return false;
506       }
507     }
508     return true;
509   }
510
511   private static boolean validateIntOccurence(JTextField field) {
512     try {
513       int a = Integer.parseInt(field.getText());
514       if (a==-1) throw new NumberFormatException();
515     } catch(NumberFormatException ex) {
516       Messages.showErrorDialog(SSRBundle.message("invalid.occurence.count"), SSRBundle.message("invalid.occurence.count"));
517       field.requestFocus();
518       return false;
519     }
520     return true;
521   }
522
523   @NotNull
524   protected Action[] createActions() {
525     return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
526   }
527
528   protected void doHelpAction() {
529     HelpManager.getInstance().invokeHelp("reference.dialogs.search.replace.structural.editvariable");
530   }
531
532   private void createUIComponents() {
533     regexp = createRegexComponent();
534     regexprForExprType = createRegexComponent();
535     formalArgType = createRegexComponent();
536     customScriptCode = new ComponentWithBrowseButton<EditorTextField>(createScriptComponent(), null);
537
538     myRegExHelpLabel = RegExHelpPopup.createRegExLink(SSRBundle.message("regular.expression.help.label"), regexp, LOG);
539     myRegExHelpLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
540   }
541
542   private static EditorTextField createRegexComponent() {
543     @NonNls final String fileName = "1.regexp";
544     final FileType fileType = getFileType(fileName);
545     final Document doc = createDocument(fileName, fileType, "");
546     return new EditorTextField(doc, myProject, fileType);
547   }
548
549   private static EditorTextField createScriptComponent() {
550     @NonNls final String fileName = "1.groovy";
551     final FileType fileType = getFileType(fileName);
552     final Document doc = createDocument(fileName, fileType, "");
553     return new EditorTextField(doc, myProject, fileType);
554   }
555
556   private static Document createDocument(final String fileName, final FileType fileType, String text) {
557     final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(fileName, fileType, text, -1, true);
558
559     return PsiDocumentManager.getInstance(myProject).getDocument(file);
560   }
561
562   private static FileType getFileType(final String fileName) {
563     FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
564     if (fileType == FileTypes.UNKNOWN) fileType = FileTypes.PLAIN_TEXT;
565     return fileType;
566   }
567
568   public static void setProject(final Project project) {
569     myProject = project;
570   }
571
572   private static class MyChangeListener implements ChangeListener {
573     private final JComponent component;
574     private final boolean inverted;
575
576     MyChangeListener(JComponent _component, boolean _inverted) {
577       component = _component;
578       inverted = _inverted;
579     }
580
581     public void stateChanged(@NotNull ChangeEvent e) {
582       final JCheckBox jCheckBox = (JCheckBox)e.getSource();
583       component.setEnabled(inverted ^ jCheckBox.isSelected());
584     }
585   }
586
587   private static class MyDocumentListener extends DocumentAdapter {
588     private final JComponent[] components;
589
590     private MyDocumentListener(JComponent... _components) {
591       components = _components;
592     }
593
594     @Override
595     public void documentChanged(DocumentEvent e) {
596       final boolean enable = e.getDocument().getTextLength() > 0;
597       for (JComponent component : components) {
598         component.setEnabled(enable);
599       }
600     }
601   }
602
603   private static Editor createEditor(final Project project, final String text, final String fileName) {
604     final FileType fileType = getFileType(fileName);
605     final Document doc = createDocument(fileName, fileType, text);
606     final Editor editor = EditorFactory.getInstance().createEditor(doc, project);
607
608     ((EditorEx)editor).setEmbeddedIntoDialogWrapper(true);
609     final EditorSettings settings = editor.getSettings();
610     settings.setLineNumbersShown(false);
611     settings.setFoldingOutlineShown(false);
612     settings.setRightMarginShown(false);
613     settings.setLineMarkerAreaShown(false);
614     settings.setIndentGuidesShown(false);
615     ((EditorEx)editor).setHighlighter(HighlighterFactory.createHighlighter(fileType, DefaultColorSchemesManager.getInstance().getAllSchemes()[0], project));
616
617     return editor;
618   }
619
620   private static class EditScriptDialog extends DialogWrapper {
621     private final Editor editor;
622     private final String title;
623
624     public EditScriptDialog(Project project, String text, Collection<String> names) {
625       super(project, true);
626       setTitle(SSRBundle.message("edit.groovy.script.constraint.title"));
627       editor = createEditor(project, text, "1.groovy");
628       title = names.size() > 0 ? "Available variables: " + StringUtil.join(names, ", ") : "";
629       init();
630     }
631
632     @Override
633     protected String getDimensionServiceKey() {
634       return getClass().getName();
635     }
636
637     @Override
638     public JComponent getPreferredFocusedComponent() {
639       return editor.getContentComponent();
640     }
641
642     protected JComponent createCenterPanel() {
643       final JPanel panel = new JPanel(new BorderLayout());
644       panel.add(editor.getComponent(), BorderLayout.CENTER);
645       if (!title.isEmpty()) {
646         panel.add(new JLabel(title), BorderLayout.SOUTH);
647       }
648       return panel;
649     }
650
651     String getScriptText() {
652       return editor.getDocument().getText();
653     }
654
655     @Override
656     protected void dispose() {
657       EditorFactory.getInstance().releaseEditor(editor);
658       super.dispose();
659     }
660   }
661 }