diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java index bb34ce3ea3e4..d4b1284198d5 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java @@ -217,8 +217,8 @@ public class ReplaceDialog extends SearchDialog { } @Override - protected void addOrReplaceSelection(final String selection) { - super.addOrReplaceSelection(selection); - addOrReplaceSelectionForEditor(selection, replaceCriteriaEdit); + protected void setText(final String text) { + super.setText(text); + setTextForEditor(text, replaceCriteriaEdit); } } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java index 0003716c9b80..9af1d8098e90 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java @@ -36,6 +36,7 @@ import java.util.stream.Stream; @State(name = "StructuralSearchPlugin", storages = @Storage(StoragePathMacros.WORKSPACE_FILE)) public class ConfigurationManager implements PersistentStateComponent { + private static final int MAX_RECENT_SIZE = 30; @NonNls static final String SEARCH_TAG_NAME = "searchConfiguration"; @NonNls static final String REPLACE_TAG_NAME = "replaceConfiguration"; @NonNls private static final String SAVE_HISTORY_ATTR_NAME = "history"; @@ -66,14 +67,17 @@ public class ConfigurationManager implements PersistentStateComponent { readConfigurations(state, configurations, historyConfigurations); } - public void addHistoryConfigurationToFront(Configuration configuration) { - historyConfigurations.remove(configuration); - historyConfigurations.add(0, configuration); + public void addHistoryConfiguration(Configuration configuration) { + historyConfigurations.remove(configuration); // move to most recent configuration.setCreated(System.currentTimeMillis()); + historyConfigurations.add(0, configuration); + while (historyConfigurations.size() > MAX_RECENT_SIZE) { + historyConfigurations.remove(historyConfigurations.size() - 1); + } } - public void removeHistoryConfiguration(Configuration configuration) { - historyConfigurations.remove(configuration); + public Configuration getMostRecentConfiguration() { + return historyConfigurations.isEmpty() ? null : historyConfigurations.get(0); } public void removeConfiguration(Configuration configuration) { @@ -148,22 +152,16 @@ public class ConfigurationManager implements PersistentStateComponent { @Nullable public Configuration findConfigurationByName(String name) { final Configuration configuration = findConfigurationByName(configurations, name); - if (configuration != null) { - return configuration; - } - return findConfigurationByName(StructuralSearchUtil.getPredefinedTemplates(), name); + return configuration != null ? configuration : findConfigurationByName(StructuralSearchUtil.getPredefinedTemplates(), name); } @Nullable private static Configuration findConfigurationByName(final Collection configurations, final String name) { - for(Configuration config : configurations) { - if (config.getName().equals(name)) return config; - } - return null; + return configurations.stream().filter(config -> config.getName().equals(name)).findFirst().orElse(null); } @NotNull - public Collection getHistoryConfigurations() { + public List getHistoryConfigurations() { return Collections.unmodifiableList(historyConfigurations); } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java index a444ba9bc837..a0fee82bbf69 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java @@ -29,6 +29,7 @@ import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Function; +import com.intellij.util.SmartList; import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; @@ -53,6 +54,7 @@ public class ExistingTemplatesComponent { private final JComponent historyPanel; private DialogWrapper owner; private final Project project; + private final SmartList queuedActions = new SmartList<>(); private ExistingTemplatesComponent(Project project) { this.project = project; @@ -83,10 +85,8 @@ public class ExistingTemplatesComponent { parent.add(node); } - final ConfigurationManager configurationManager = ConfigurationManager.getInstance(project); userTemplatesNode = new DefaultMutableTreeNode(SSRBundle.message("user.defined.category")); root.add(userTemplatesNode); - setUserTemplates(configurationManager); for (final DefaultMutableTreeNode nodeToExpand : nodesToExpand) { patternTree.expandPath(new TreePath(new Object[]{root, nodeToExpand})); @@ -115,7 +115,7 @@ public class ExistingTemplatesComponent { patternTree.addSelectionRow(rows[0] - 1); } patternTreeModel.removeNodeFromParent(node); - configurationManager.removeConfiguration(configuration); + queuedActions.add(() -> ConfigurationManager.getInstance(project).removeConfiguration(configuration)); } }).setRemoveActionUpdater(new AnActionButtonUpdater() { @Override @@ -140,14 +140,13 @@ public class ExistingTemplatesComponent { configureSelectTemplateAction(patternTree); - historyModel = new CollectionListModel<>(configurationManager.getHistoryConfigurations()); + historyModel = new CollectionListModel<>(); historyPanel = new JPanel(new BorderLayout()); historyPanel.add(BorderLayout.NORTH, new JLabel(SSRBundle.message("used.templates"))); historyList = new JBList<>(historyModel); historyPanel.add(BorderLayout.CENTER, ScrollPaneFactory.createScrollPane(historyList)); historyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - historyList.setSelectedIndex(0); ListSpeedSearch speedSearch = new ListSpeedSearch<>(historyList, (Function)Configuration::getName); historyList.setCellRenderer(new ExistingTemplatesListCellRenderer(speedSearch)); @@ -171,7 +170,8 @@ public class ExistingTemplatesComponent { } } - public void setUserTemplates(ConfigurationManager configurationManager) { + private void initialize() { + final ConfigurationManager configurationManager = ConfigurationManager.getInstance(project); userTemplatesNode.removeAllChildren(); for (final Configuration config : configurationManager.getConfigurations()) { userTemplatesNode.add(new DefaultMutableTreeNode(config)); @@ -179,6 +179,8 @@ public class ExistingTemplatesComponent { patternTreeModel.reload(userTemplatesNode); patternTree.expandPath(new TreePath(new Object[]{patternTreeModel.getRoot(), userTemplatesNode})); + historyModel.replaceAll(configurationManager.getHistoryConfigurations()); + historyList.setSelectedIndex(0); } private void configureSelectTemplateAction(JComponent component) { @@ -232,7 +234,9 @@ public class ExistingTemplatesComponent { } public static ExistingTemplatesComponent getInstance(Project project) { - return ServiceManager.getService(project, ExistingTemplatesComponent.class); + final ExistingTemplatesComponent existingTemplatesComponent = ServiceManager.getService(project, ExistingTemplatesComponent.class); + existingTemplatesComponent.initialize(); + return existingTemplatesComponent; } private static class ExistingTemplatesListCellRenderer extends ColoredListCellRenderer { @@ -297,21 +301,7 @@ public class ExistingTemplatesComponent { } } - void addConfigurationToHistory(Configuration configuration) { - historyModel.remove(configuration); - historyModel.add(0, configuration); - final ConfigurationManager configurationManager = ConfigurationManager.getInstance(project); - configurationManager.addHistoryConfigurationToFront(configuration); - historyList.setSelectedIndex(0); - - if (historyModel.getSize() > 25) { - configurationManager.removeHistoryConfiguration(historyModel.getElementAt(25)); - // we add by one! - historyModel.remove(25); - } - } - - public JList getHistoryList() { + public JList getHistoryList() { return historyList; } @@ -322,4 +312,11 @@ public class ExistingTemplatesComponent { public void setOwner(DialogWrapper owner) { this.owner = owner; } + + public void finish(boolean performQueuedActions) { + if (performQueuedActions) { + queuedActions.forEach(a -> a.run()); + } + queuedActions.clear(); + } } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java index bc14ccf7dc48..1c932acce74d 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java @@ -97,8 +97,6 @@ public class SearchDialog extends DialogWrapper { private final Alarm myAlarm; public static final String USER_DEFINED = SSRBundle.message("new.template.defaultname"); - protected final ExistingTemplatesComponent existingTemplatesComponent; - private boolean useLastConfiguration; @NonNls private FileType ourFtSearchVariant = StructuralSearchUtil.getDefaultFileType(); @@ -130,7 +128,6 @@ public class SearchDialog extends DialogWrapper { setOKButtonText(FindBundle.message("find.dialog.find.button")); } - existingTemplatesComponent = ExistingTemplatesComponent.getInstance(this.searchContext.getProject()); model = new SearchModel(createConfiguration()); init(); @@ -141,7 +138,7 @@ public class SearchDialog extends DialogWrapper { this.useLastConfiguration = useLastConfiguration; } - private void setSearchPattern(final Configuration config) { + void setSearchPattern(final Configuration config) { model.setShadowConfig(config); setValuesFromConfig(config); initiateValidation(); @@ -293,7 +290,7 @@ public class SearchDialog extends DialogWrapper { updateDialectsAndContexts(); } - private void updateEditor() { + void updateEditor() { if (myContentPanel != null) { if (myEditorPanel != null) { myContentPanel.remove(myEditorPanel); @@ -306,7 +303,7 @@ public class SearchDialog extends DialogWrapper { } } - private void updateDialectsAndContexts() { + void updateDialectsAndContexts() { final FileType fileType = (FileType)fileTypes.getSelectedItem(); if (fileType instanceof LanguageFileType) { Language language = ((LanguageFileType)fileType).getLanguage(); @@ -418,7 +415,7 @@ public class SearchDialog extends DialogWrapper { } } - private void setDialogTitle(final Configuration configuration) { + void setDialogTitle(final Configuration configuration) { setTitle(getDefaultTitle() + " - " + configuration.getName()); } @@ -428,11 +425,11 @@ public class SearchDialog extends DialogWrapper { return configuration; } - protected void addOrReplaceSelection(final String selection) { - addOrReplaceSelectionForEditor(selection, searchCriteriaEdit); + protected void setText(String text) { + setTextForEditor(text, searchCriteriaEdit); } - protected final void addOrReplaceSelectionForEditor(final String selection, Editor editor) { + protected final void setTextForEditor(final String selection, Editor editor) { final Project project = searchContext.getProject(); UIUtil.setContent(editor, selection, 0, -1, project); final Document document = editor.getDocument(); @@ -575,16 +572,11 @@ public class SearchDialog extends DialogWrapper { @Override public void actionPerformed(ActionEvent e) { - final Project project = searchContext.getProject(); - final ConfigurationManager configurationManager = ConfigurationManager.getInstance(project); - final Configuration configuration = getConfiguration(); - if (!configurationManager.showSaveTemplateAsDialog(configuration)) { + if (!ConfigurationManager.getInstance(getProject()).showSaveTemplateAsDialog(configuration)) { return; } setDialogTitle(configuration); - - existingTemplatesComponent.setUserTemplates(configurationManager); } }) ); @@ -691,17 +683,15 @@ public class SearchDialog extends DialogWrapper { final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasSelection()) { - addOrReplaceSelection(selectionModel.getSelectedText()); - existingTemplatesComponent.getPatternTree().setSelectionPath(null); - existingTemplatesComponent.getHistoryList().setSelectedIndex(-1); + setText(selectionModel.getSelectedText()); setSomeText = true; } } if (!setSomeText) { - int selection = existingTemplatesComponent.getHistoryList().getSelectedIndex(); - if (selection != -1) { - setValuesFromConfig((Configuration)existingTemplatesComponent.getHistoryList().getSelectedValue()); + final Configuration configuration = ConfigurationManager.getInstance(getProject()).getMostRecentConfiguration(); + if (configuration != null) { + setValuesFromConfig(configuration); } } } @@ -746,7 +736,7 @@ public class SearchDialog extends DialogWrapper { //} } filterOutUnusedVariableConstraints(configuration); - existingTemplatesComponent.addConfigurationToHistory(configuration); + ConfigurationManager.getInstance(getProject()).addHistoryConfiguration(configuration); startSearching(); } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java index c39a1b9ace06..2d573ecf34d7 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java @@ -39,6 +39,7 @@ import javax.swing.tree.TreePath; import java.awt.*; import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** * @author Maxim.Mossienko @@ -60,7 +61,7 @@ public class SelectTemplateDialog extends DialogWrapper { @NonNls private static final String SELECT_TEMPLATE_CARD = "SelectCard"; public SelectTemplateDialog(Project project, boolean showHistory, boolean replace) { - super(project, false); + super(project, true); this.project = project; this.showHistory = showHistory; @@ -89,6 +90,18 @@ public class SelectTemplateDialog extends DialogWrapper { setupListeners(); } + @Override + protected void doOKAction() { + super.doOKAction(); + existingTemplatesComponent.finish(true); + } + + @Override + public void doCancelAction() { + super.doCancelAction(); + existingTemplatesComponent.finish(false); + } + class MySelectionListener implements TreeSelectionListener, ListSelectionListener { public void valueChanged(TreeSelectionEvent e) { if (e.getNewLeadSelectionPath() != null) { @@ -196,23 +209,17 @@ public class SelectTemplateDialog extends DialogWrapper { selectionListener = new MySelectionListener(); if (showHistory) { - existingTemplatesComponent.getHistoryList().getSelectionModel().addListSelectionListener( - selectionListener - ); + existingTemplatesComponent.getHistoryList().getSelectionModel().addListSelectionListener(selectionListener); } else { - existingTemplatesComponent.getPatternTree().getSelectionModel().addTreeSelectionListener( - selectionListener - ); + existingTemplatesComponent.getPatternTree().getSelectionModel().addTreeSelectionListener(selectionListener); } } private void removeListeners() { existingTemplatesComponent.setOwner(null); if (showHistory) { - existingTemplatesComponent.getHistoryList().getSelectionModel().removeListSelectionListener( - selectionListener - ); + existingTemplatesComponent.getHistoryList().getSelectionModel().removeListSelectionListener(selectionListener); } else { existingTemplatesComponent.getPatternTree().getSelectionModel().removeTreeSelectionListener(selectionListener); @@ -279,17 +286,8 @@ public class SelectTemplateDialog extends DialogWrapper { @NotNull public Configuration[] getSelectedConfigurations() { if (showHistory) { - Object[] selectedValues = existingTemplatesComponent.getHistoryList().getSelectedValues(); - if (selectedValues == null) { - return new Configuration[0]; - } - Collection configurations = new ArrayList<>(); - for (Object selectedValue : selectedValues) { - if (selectedValue instanceof Configuration) { - configurations.add((Configuration)selectedValue); - } - } - return configurations.toArray(new Configuration[configurations.size()]); + final List selectedValues = existingTemplatesComponent.getHistoryList().getSelectedValuesList(); + return selectedValues.toArray(Configuration.EMPTY_ARRAY); } else { TreePath[] paths = existingTemplatesComponent.getPatternTree().getSelectionModel().getSelectionPaths();