2 * Copyright 2000-2016 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.structuralsearch.plugin.ui;
18 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
19 import com.intellij.codeInsight.template.impl.Variable;
20 import com.intellij.find.FindBundle;
21 import com.intellij.find.FindSettings;
22 import com.intellij.ide.IdeBundle;
23 import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
24 import com.intellij.lang.Language;
25 import com.intellij.lang.LanguageUtil;
26 import com.intellij.openapi.application.ApplicationManager;
27 import com.intellij.openapi.application.Result;
28 import com.intellij.openapi.command.WriteCommandAction;
29 import com.intellij.openapi.diagnostic.Logger;
30 import com.intellij.openapi.editor.Document;
31 import com.intellij.openapi.editor.Editor;
32 import com.intellij.openapi.editor.EditorFactory;
33 import com.intellij.openapi.editor.SelectionModel;
34 import com.intellij.openapi.editor.event.DocumentEvent;
35 import com.intellij.openapi.editor.event.DocumentListener;
36 import com.intellij.openapi.fileTypes.FileType;
37 import com.intellij.openapi.fileTypes.LanguageFileType;
38 import com.intellij.openapi.fileTypes.impl.FileTypeRenderer;
39 import com.intellij.openapi.progress.ProcessCanceledException;
40 import com.intellij.openapi.project.Project;
41 import com.intellij.openapi.ui.ComboBox;
42 import com.intellij.openapi.ui.DialogWrapper;
43 import com.intellij.openapi.util.Disposer;
44 import com.intellij.openapi.util.TextRange;
45 import com.intellij.openapi.wm.ToolWindow;
46 import com.intellij.openapi.wm.ToolWindowId;
47 import com.intellij.openapi.wm.ToolWindowManager;
48 import com.intellij.psi.PsiDocumentManager;
49 import com.intellij.psi.PsiElement;
50 import com.intellij.psi.PsiFile;
51 import com.intellij.psi.codeStyle.CodeStyleManager;
52 import com.intellij.psi.search.GlobalSearchScope;
53 import com.intellij.psi.search.SearchScope;
54 import com.intellij.structuralsearch.*;
55 import com.intellij.structuralsearch.impl.matcher.MatcherImpl;
56 import com.intellij.structuralsearch.plugin.StructuralSearchPlugin;
57 import com.intellij.ui.ComboboxSpeedSearch;
58 import com.intellij.ui.IdeBorderFactory;
59 import com.intellij.ui.ListCellRendererWrapper;
60 import com.intellij.ui.TitledSeparator;
61 import com.intellij.util.Alarm;
62 import com.intellij.util.ui.JBUI;
63 import org.jetbrains.annotations.NonNls;
64 import org.jetbrains.annotations.NotNull;
68 import java.awt.event.ActionEvent;
69 import java.awt.event.ItemEvent;
70 import java.awt.event.ItemListener;
72 import java.util.List;
75 * Class to show the user the request for search
77 @SuppressWarnings({"RefusedBequest", "AssignmentToStaticFieldFromInstanceMethod"})
78 public class SearchDialog extends DialogWrapper {
79 protected SearchContext searchContext;
82 protected Editor searchCriteriaEdit;
84 // options of search scope
85 private ScopeChooserCombo myScopeChooserCombo;
87 private JCheckBox recursiveMatching;
88 private JCheckBox caseSensitiveMatch;
90 private JComboBox<FileType> fileTypes;
91 private JComboBox<String> contexts;
92 private JComboBox<Language> dialects;
93 private JLabel status;
94 private JLabel statusText;
96 protected SearchModel model;
97 private JCheckBox openInNewTab;
98 private final Alarm myAlarm;
100 public static final String USER_DEFINED = SSRBundle.message("new.template.defaultname");
101 protected final ExistingTemplatesComponent existingTemplatesComponent;
103 private boolean useLastConfiguration;
105 @NonNls private FileType ourFtSearchVariant = StructuralSearchUtil.getDefaultFileType();
106 private static Language ourDialect = null;
107 private static String ourContext = null;
109 private final boolean myShowScopePanel;
110 private final boolean myRunFindActionOnClose;
111 private boolean myDoingOkAction;
113 private String mySavedEditorText;
114 private JPanel myContentPanel;
115 private JComponent myEditorPanel;
117 public SearchDialog(SearchContext searchContext) {
118 this(searchContext, true, true);
121 public SearchDialog(SearchContext searchContext, boolean showScope, boolean runFindActionOnClose) {
122 super(searchContext.getProject(), true);
124 if (showScope) setModal(false);
125 myShowScopePanel = showScope;
126 myRunFindActionOnClose = runFindActionOnClose;
127 this.searchContext = searchContext;
128 setTitle(getDefaultTitle());
130 if (runFindActionOnClose) {
131 setOKButtonText(FindBundle.message("find.dialog.find.button"));
134 existingTemplatesComponent = ExistingTemplatesComponent.getInstance(this.searchContext.getProject());
135 model = new SearchModel(createConfiguration());
138 myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD,myDisposable);
141 public void setUseLastConfiguration(boolean useLastConfiguration) {
142 this.useLastConfiguration = useLastConfiguration;
145 private void setSearchPattern(final Configuration config) {
146 model.setShadowConfig(config);
147 setValuesFromConfig(config);
148 initiateValidation();
151 protected Editor createEditor(final SearchContext searchContext, String text) {
152 Editor editor = null;
154 if (fileTypes != null) {
155 final FileType fileType = (FileType)fileTypes.getSelectedItem();
156 final Language dialect = (Language)dialects.getSelectedItem();
158 final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(fileType);
159 if (profile != null) {
160 editor = profile.createEditor(searchContext, fileType, dialect, text, useLastConfiguration);
164 if (editor == null) {
165 final EditorFactory factory = EditorFactory.getInstance();
166 final Document document = factory.createDocument("");
167 editor = factory.createEditor(document, searchContext.getProject());
168 editor.getSettings().setFoldingOutlineShown(false);
171 editor.getDocument().addDocumentListener(new DocumentListener() {
173 public void beforeDocumentChange(final DocumentEvent event) {
177 public void documentChanged(final DocumentEvent event) {
178 initiateValidation();
185 private void initiateValidation() {
186 myAlarm.cancelAllRequests();
187 myAlarm.addRequest(() -> {
189 ApplicationManager.getApplication().runReadAction(() -> {
190 final boolean valid = isValid();
191 ApplicationManager.getApplication().invokeLater(() -> {
193 getOKAction().setEnabled(false);
196 getOKAction().setEnabled(true);
197 reportMessage(null, null);
202 catch (ProcessCanceledException e) {
205 catch (RuntimeException e) {
206 Logger.getInstance(SearchDialog.class).error(e);
211 protected void buildOptions(JPanel searchOptions) {
212 recursiveMatching = new JCheckBox(SSRBundle.message("recursive.matching.checkbox"), true);
213 if (isRecursiveSearchEnabled()) {
214 searchOptions.add(UIUtil.createOptionLine(recursiveMatching));
217 caseSensitiveMatch = new JCheckBox(FindBundle.message("find.options.case.sensitive"), true);
218 searchOptions.add(UIUtil.createOptionLine(caseSensitiveMatch));
220 final List<FileType> types = new ArrayList<>();
222 for (FileType fileType : StructuralSearchUtil.getSuitableFileTypes()) {
223 if (StructuralSearchUtil.getProfileByFileType(fileType) != null) {
227 Collections.sort(types, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
229 final DefaultComboBoxModel<FileType> comboBoxModel = new DefaultComboBoxModel<>(types.toArray(new FileType[types.size()]));
230 fileTypes = new ComboBox<>(comboBoxModel);
231 fileTypes.setRenderer(new FileTypeRenderer());
232 new ComboboxSpeedSearch(fileTypes) {
234 protected String getElementText(Object element) {
235 return ((FileType)element).getName();
238 contexts = new ComboBox<>();
239 contexts.setPreferredSize(new Dimension(60, -1));
241 dialects = new ComboBox<>();
242 dialects.setRenderer(new ListCellRendererWrapper<Language>() {
244 public void customize(JList list, Language value, int index, boolean selected, boolean hasFocus) {
249 setText(value.getDisplayName());
253 dialects.addItemListener(new ItemListener() {
255 public void itemStateChanged(ItemEvent e) {
259 new ComboboxSpeedSearch(dialects);
260 dialects.setPreferredSize(new Dimension(120, -1));
262 final JLabel jLabel = new JLabel(SSRBundle.message("search.dialog.file.type.label"));
263 final JLabel jLabel2 = new JLabel(SSRBundle.message("search.dialog.context.label"));
264 final JLabel jLabel3 = new JLabel(SSRBundle.message("search.dialog.file.dialect.label"));
266 UIUtil.createOptionLine(
270 (JComponent)Box.createHorizontalStrut(8),
273 (JComponent)Box.createHorizontalStrut(8),
280 jLabel.setLabelFor(fileTypes);
281 jLabel2.setLabelFor(contexts);
282 jLabel3.setLabelFor(dialects);
284 detectFileTypeAndDialect();
286 fileTypes.setSelectedItem(ourFtSearchVariant);
287 fileTypes.addItemListener(new ItemListener() {
289 public void itemStateChanged(ItemEvent e) {
290 if (e.getStateChange() == ItemEvent.SELECTED) {
291 updateDialectsAndContexts();
293 initiateValidation();
297 dialects.setSelectedItem(ourDialect);
298 contexts.setSelectedItem(ourContext);
300 updateDialectsAndContexts();
303 private void updateEditor() {
304 if (myContentPanel != null) {
305 if (myEditorPanel != null) {
306 myContentPanel.remove(myEditorPanel);
308 disposeEditorContent();
309 myEditorPanel = createEditorContent();
310 myContentPanel.add(myEditorPanel, BorderLayout.CENTER);
311 myContentPanel.revalidate();
312 searchCriteriaEdit.putUserData(SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY, model.getConfig());
316 private void updateDialectsAndContexts() {
317 final FileType fileType = (FileType)fileTypes.getSelectedItem();
318 if (fileType instanceof LanguageFileType) {
319 Language language = ((LanguageFileType)fileType).getLanguage();
320 Language[] languageDialects = LanguageUtil.getLanguageDialects(language);
321 Arrays.sort(languageDialects, Comparator.comparing(Language::getDisplayName));
322 Language[] variants = new Language[languageDialects.length + 1];
324 System.arraycopy(languageDialects, 0, variants, 1, languageDialects.length);
325 dialects.setModel(new DefaultComboBoxModel<>(variants));
326 dialects.setEnabled(variants.length > 1);
329 final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(fileType);
331 if (profile instanceof StructuralSearchProfileBase) {
332 final String[] contextNames = ((StructuralSearchProfileBase)profile).getContextNames();
333 if (contextNames.length > 0) {
334 contexts.setModel(new DefaultComboBoxModel<>(contextNames));
335 contexts.setSelectedItem(contextNames[0]);
336 contexts.setEnabled(true);
340 contexts.setSelectedItem(null);
341 contexts.setEnabled(false);
344 private void detectFileTypeAndDialect() {
345 final PsiFile file = searchContext.getFile();
347 PsiElement context = null;
349 if (searchContext.getEditor() != null) {
350 context = file.findElementAt(searchContext.getEditor().getCaretModel().getOffset());
351 if (context != null) {
352 context = context.getParent();
355 if (context == null) {
359 FileType detectedFileType = null;
361 StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(context);
362 if (profile != null) {
363 FileType fileType = profile.detectFileType(context);
364 if (fileType != null) {
365 detectedFileType = fileType;
369 if (detectedFileType == null) {
370 for (FileType fileType : StructuralSearchUtil.getSuitableFileTypes()) {
371 if (fileType instanceof LanguageFileType && ((LanguageFileType)fileType).getLanguage().equals(context.getLanguage())) {
372 detectedFileType = fileType;
378 ourFtSearchVariant = detectedFileType != null ?
380 StructuralSearchUtil.getDefaultFileType();
384 protected boolean isRecursiveSearchEnabled() {
388 public void setValuesFromConfig(Configuration configuration) {
389 setDialogTitle(configuration);
390 final MatchOptions matchOptions = configuration.getMatchOptions();
394 matchOptions.getSearchPattern(),
396 searchCriteriaEdit.getDocument().getTextLength(),
397 searchContext.getProject()
400 model.getConfig().getMatchOptions().setSearchPattern(
401 matchOptions.getSearchPattern()
404 recursiveMatching.setSelected(
405 isRecursiveSearchEnabled() && matchOptions.isRecursiveSearch()
408 caseSensitiveMatch.setSelected(
409 matchOptions.isCaseSensitiveMatch()
412 model.getConfig().getMatchOptions().clearVariableConstraints();
413 for (String name : matchOptions.getVariableConstraintNames()) {
414 final MatchVariableConstraint constraint = (MatchVariableConstraint)matchOptions.getVariableConstraint(name).clone();
415 model.getConfig().getMatchOptions().addVariableConstraint(constraint);
418 MatchOptions options = configuration.getMatchOptions();
419 StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(options.getFileType());
420 assert profile != null;
421 fileTypes.setSelectedItem(options.getFileType());
422 dialects.setSelectedItem(options.getDialect());
423 if (options.getPatternContext() != null) {
424 contexts.setSelectedItem(options.getPatternContext());
428 private void setDialogTitle(final Configuration configuration) {
429 setTitle(getDefaultTitle() + " - " + configuration.getName());
432 public Configuration createConfiguration() {
433 SearchConfiguration configuration = new SearchConfiguration();
434 configuration.setName(USER_DEFINED);
435 return configuration;
438 protected void addOrReplaceSelection(final String selection) {
439 addOrReplaceSelectionForEditor(selection, searchCriteriaEdit);
442 protected final void addOrReplaceSelectionForEditor(final String selection, Editor editor) {
443 final Project project = searchContext.getProject();
444 UIUtil.setContent(editor, selection, 0, -1, project);
445 final Document document = editor.getDocument();
446 editor.getSelectionModel().setSelection(0, document.getTextLength());
447 final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
448 documentManager.commitDocument(document);
449 final PsiFile file = documentManager.getPsiFile(document);
450 if (file == null) return;
452 new WriteCommandAction(project, file) {
453 @Override protected void run(@NotNull Result result) throws Throwable {
454 CodeStyleManager.getInstance(project).adjustLineIndent(file, new TextRange(0, document.getTextLength()));
459 protected void startSearching() {
460 new SearchCommand(model.getConfig(), searchContext).startSearching();
463 protected String getDefaultTitle() {
464 return SSRBundle.message("structural.search.title");
467 protected JComponent createEditorContent() {
468 final JPanel result = new JPanel(new BorderLayout());
470 searchCriteriaEdit = createEditor(searchContext, mySavedEditorText != null ? mySavedEditorText : "");
471 result.add(BorderLayout.CENTER, searchCriteriaEdit.getComponent());
472 result.setMinimumSize(new Dimension(150, 100));
474 final JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0));
475 labelPanel.add(new JLabel(SSRBundle.message("search.template")));
477 labelPanel.add(UIUtil.createCompleteMatchInfo(() -> model.getConfig()));
478 result.add(BorderLayout.NORTH, labelPanel);
483 protected int getRowsCount() {
488 protected JComponent createCenterPanel() {
489 myContentPanel = new JPanel(new BorderLayout());
490 myEditorPanel = createEditorContent();
491 myContentPanel.add(BorderLayout.CENTER, myEditorPanel);
492 myContentPanel.add(BorderLayout.SOUTH, Box.createVerticalStrut(8));
493 JComponent centerPanel = new JPanel(new BorderLayout());
495 JPanel panel = new JPanel(new BorderLayout());
496 panel.add(BorderLayout.CENTER, myContentPanel);
497 panel.add(BorderLayout.SOUTH, createTemplateManagementButtons());
498 centerPanel.add(BorderLayout.CENTER, panel);
501 JPanel optionsContent = new JPanel(new BorderLayout());
502 centerPanel.add(BorderLayout.SOUTH, optionsContent);
504 JPanel searchOptions = new JPanel();
505 searchOptions.setLayout(new GridLayout(getRowsCount(), 1, 0, 0));
506 searchOptions.setBorder(IdeBorderFactory.createTitledBorder(SSRBundle.message("ssdialog.options.group.border"),
509 myScopeChooserCombo = new ScopeChooserCombo(
510 searchContext.getProject(),
513 FindSettings.getInstance().getDefaultScopeName()
515 Disposer.register(myDisposable, myScopeChooserCombo);
516 JPanel allOptions = new JPanel(new BorderLayout());
517 if (myShowScopePanel) {
518 JPanel scopePanel = new JPanel(new GridBagLayout());
520 TitledSeparator separator = new TitledSeparator(SSRBundle.message("search.dialog.scope.label"), myScopeChooserCombo.getComboBox());
521 scopePanel.add(separator, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
522 JBUI.insetsTop(5), 0, 0));
524 scopePanel.add(myScopeChooserCombo, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
525 JBUI.insetsLeft(10), 0, 0));
532 myScopeChooserCombo.getComboBox().addItemListener(new ItemListener() {
534 public void itemStateChanged(ItemEvent e) {
535 initiateValidation();
540 buildOptions(searchOptions);
542 allOptions.add(searchOptions, BorderLayout.CENTER);
543 optionsContent.add(allOptions, BorderLayout.CENTER);
545 if (myRunFindActionOnClose) {
546 JPanel panel = new JPanel(new BorderLayout());
547 panel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
548 openInNewTab = new JCheckBox(FindBundle.message("find.open.in.new.tab.checkbox"));
549 openInNewTab.setSelected(FindSettings.getInstance().isShowResultsInSeparateView());
550 ToolWindow findWindow = ToolWindowManager.getInstance(searchContext.getProject()).getToolWindow(ToolWindowId.FIND);
551 openInNewTab.setEnabled(findWindow != null && findWindow.isAvailable());
552 panel.add(openInNewTab, BorderLayout.EAST);
554 optionsContent.add(BorderLayout.SOUTH, panel);
563 protected JComponent createSouthPanel() {
564 final JPanel statusPanel = new JPanel(new BorderLayout(5, 0));
565 statusPanel.add(super.createSouthPanel(), BorderLayout.NORTH);
566 statusPanel.add(statusText = new JLabel(SSRBundle.message("status.message")), BorderLayout.WEST);
567 statusPanel.add(status = new JLabel(), BorderLayout.CENTER);
571 private JPanel createTemplateManagementButtons() {
572 JPanel panel = new JPanel(null);
573 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
574 panel.add(Box.createHorizontalGlue());
577 createJButtonForAction(new AbstractAction() {
579 putValue(NAME, SSRBundle.message("save.template.text.button"));
583 public void actionPerformed(ActionEvent e) {
584 String name = showSaveTemplateAsDialog();
587 final Project project = searchContext.getProject();
588 final ConfigurationManager configurationManager = ConfigurationManager.getInstance(project);
589 final Collection<Configuration> configurations = configurationManager.getConfigurations();
591 if (configurations != null) {
592 name = ConfigurationManager.findAppropriateName(configurations, name, project);
593 if (name == null) return;
596 final Configuration configuration = model.getConfig();
597 model = new SearchModel(createConfiguration());
598 model.setShadowConfig(configuration);
599 configuration.setName(name);
600 setValuesToConfig(configuration);
601 setDialogTitle(configuration);
603 filterOutUnusedVariableConstraints(configuration);
604 configurationManager.addConfiguration(configuration);
605 existingTemplatesComponent.setUserTemplates(configurationManager);
611 panel.add(Box.createHorizontalStrut(8));
614 createJButtonForAction(
615 new AbstractAction() {
617 putValue(NAME, SSRBundle.message("edit.variables.button"));
621 public void actionPerformed(ActionEvent e) {
622 EditVarConstraintsDialog.setProject(searchContext.getProject());
623 new EditVarConstraintsDialog(
624 searchContext.getProject(),
625 model.getConfig(), getVariablesFromListeners(),
626 (FileType)fileTypes.getSelectedItem()
628 initiateValidation();
629 EditVarConstraintsDialog.setProject(null);
636 Box.createHorizontalStrut(8)
640 createJButtonForAction(
641 new AbstractAction() {
643 putValue(NAME, SSRBundle.message("history.button"));
647 public void actionPerformed(ActionEvent e) {
648 SelectTemplateDialog dialog = new SelectTemplateDialog(searchContext.getProject(), true, isReplaceDialog());
649 if (!dialog.showAndGet()) {
652 Configuration[] configurations = dialog.getSelectedConfigurations();
653 if (configurations.length == 1) {
654 setSearchPattern(configurations[0]);
662 Box.createHorizontalStrut(8)
666 createJButtonForAction(
667 new AbstractAction() {
669 putValue(NAME, SSRBundle.message("copy.existing.template.button"));
673 public void actionPerformed(ActionEvent e) {
674 SelectTemplateDialog dialog = new SelectTemplateDialog(searchContext.getProject(), false, isReplaceDialog());
675 if (!dialog.showAndGet()) {
678 Configuration[] configurations = dialog.getSelectedConfigurations();
679 if (configurations.length == 1) {
680 setSearchPattern(configurations[0]);
690 protected List<Variable> getVariablesFromListeners() {
691 return getVarsFrom(searchCriteriaEdit);
694 protected static List<Variable> getVarsFrom(Editor searchCriteriaEdit) {
695 SubstitutionShortInfoHandler handler = searchCriteriaEdit.getUserData(UIUtil.LISTENER_KEY);
696 return (handler == null) ? new ArrayList<>() : new ArrayList<>(handler.getVariables());
699 public final Project getProject() {
700 return searchContext.getProject();
703 public String showSaveTemplateAsDialog() {
704 return ConfigurationManager.showSaveTemplateAsDialog(
705 model.getShadowConfig() != null ? model.getShadowConfig().getName() : SSRBundle.message("user.defined.category"),
706 searchContext.getProject()
710 protected boolean isReplaceDialog() {
716 StructuralSearchPlugin.getInstance(getProject()).setDialogVisible(true);
718 if (!useLastConfiguration) {
719 final Editor editor = searchContext.getEditor();
720 boolean setSomeText = false;
722 if (editor != null) {
723 final SelectionModel selectionModel = editor.getSelectionModel();
725 if (selectionModel.hasSelection()) {
726 addOrReplaceSelection(selectionModel.getSelectedText());
727 existingTemplatesComponent.getPatternTree().setSelectionPath(null);
728 existingTemplatesComponent.getHistoryList().setSelectedIndex(-1);
734 int selection = existingTemplatesComponent.getHistoryList().getSelectedIndex();
735 if (selection != -1) {
736 setValuesFromConfig((Configuration)existingTemplatesComponent.getHistoryList().getSelectedValue());
741 initiateValidation();
747 public JComponent getPreferredFocusedComponent() {
748 return searchCriteriaEdit.getContentComponent();
751 // Performs ok action
753 protected void doOKAction() {
754 SearchScope selectedScope = getSelectedScope();
755 if (selectedScope == null) return;
757 myDoingOkAction = true;
758 boolean result = isValid();
759 myDoingOkAction = false;
762 myAlarm.cancelAllRequests();
764 if (!myRunFindActionOnClose) return;
766 final FindSettings findSettings = FindSettings.getInstance();
767 findSettings.setDefaultScopeName(selectedScope.getDisplayName());
768 findSettings.setShowResultsInSeparateView(openInNewTab.isSelected());
771 final Configuration configuration = model.getConfig();
772 if (model.getShadowConfig() != null) {
773 if (model.getShadowConfig().isPredefined()) {
774 configuration.setName(model.getShadowConfig().getName()
777 // // user template, save it
778 // setValuesToConfig(model.getShadowConfig());
781 filterOutUnusedVariableConstraints(configuration);
782 existingTemplatesComponent.addConfigurationToHistory(configuration);
786 catch (MalformedPatternException ex) {
787 reportMessage("this.pattern.is.malformed.message", searchCriteriaEdit, ex.getMessage());
791 private void filterOutUnusedVariableConstraints(Configuration configuration) {
792 final List<Variable> variables = getVariablesFromListeners();
793 final List<String> variableNames = new ArrayList<>();
794 for (Variable variable : variables) {
795 variableNames.add(variable.getName());
797 variableNames.add(Configuration.CONTEXT_VAR_NAME);
798 configuration.getMatchOptions().retainVariableConstraints(variableNames);
801 public Configuration getConfiguration() {
802 return model.getConfig();
805 private SearchScope getSelectedScope() {
806 return myScopeChooserCombo.getSelectedScope();
809 protected boolean isValid() {
810 setValuesToConfig(model.getConfig());
811 boolean result = true;
814 MatcherImpl.validate(searchContext.getProject(), model.getConfig().getMatchOptions());
816 catch (MalformedPatternException ex) {
817 if (myRunFindActionOnClose) {
818 reportMessage("this.pattern.is.malformed.message", searchCriteriaEdit, (ex.getMessage() != null) ? ex.getMessage() : "");
822 catch (UnsupportedPatternException ex) {
823 reportMessage("this.pattern.is.unsupported.message", searchCriteriaEdit, ex.getMessage());
830 protected void reportMessage(@NonNls final String messageId, final Editor editor, final Object... params) {
831 com.intellij.util.ui.UIUtil.invokeLaterIfNeeded(() -> {
832 final String message = messageId != null ? SSRBundle.message(messageId, params) : "";
833 status.setText(message);
834 status.setToolTipText(message);
836 statusText.setLabelFor(editor != null ? editor.getContentComponent() : null);
840 protected void setValuesToConfig(Configuration config) {
842 MatchOptions options = config.getMatchOptions();
844 boolean searchWithinHierarchy = IdeBundle.message("scope.class.hierarchy").equals(myScopeChooserCombo.getSelectedScopeName());
845 // We need to reset search within hierarchy scope during online validation since the scope works with user participation
847 searchWithinHierarchy && !myDoingOkAction ? GlobalSearchScope.projectScope(getProject()) : myScopeChooserCombo.getSelectedScope());
848 options.setLooseMatching(true);
849 options.setRecursiveSearch(isRecursiveSearchEnabled() && recursiveMatching.isSelected());
851 ourFtSearchVariant = (FileType)fileTypes.getSelectedItem();
852 ourDialect = (Language)dialects.getSelectedItem();
853 ourContext = (String)contexts.getSelectedItem();
854 FileType fileType = ourFtSearchVariant;
855 options.setFileType(fileType);
856 options.setDialect(ourDialect);
857 options.setPatternContext(ourContext);
859 options.setSearchPattern(searchCriteriaEdit.getDocument().getText());
860 options.setCaseSensitiveMatch(caseSensitiveMatch.isSelected());
864 protected String getDimensionServiceKey() {
865 return "#com.intellij.structuralsearch.plugin.ui.SearchDialog";
869 public void dispose() {
870 disposeEditorContent();
872 myAlarm.cancelAllRequests();
875 StructuralSearchPlugin.getInstance(getProject()).setDialogVisible(false);
878 protected void disposeEditorContent() {
879 mySavedEditorText = searchCriteriaEdit.getDocument().getText();
881 // this will remove from myExcludedSet
882 final PsiFile file = PsiDocumentManager.getInstance(searchContext.getProject()).getPsiFile(searchCriteriaEdit.getDocument());
884 DaemonCodeAnalyzer.getInstance(searchContext.getProject()).setHighlightingEnabled(file, true);
887 EditorFactory.getInstance().releaseEditor(searchCriteriaEdit);
891 protected String getHelpId() {
892 return "find.structuredSearch";
895 public SearchContext getSearchContext() {
896 return searchContext;