From 1eecc663ed1bf831156f2e207c9ba91a17403dcc Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Mon, 23 Apr 2018 20:59:14 +0300 Subject: [PATCH] Postfix templates: allow to duplicate postfix templates (IDEA-190017) --- .../PostfixTemplatesCheckboxTree.java | 44 ++++++++++++++++++- .../PostfixTemplatesConfigurable.java | 26 ++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesCheckboxTree.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesCheckboxTree.java index e1b3ace7a2cf..767f3a327ffe 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesCheckboxTree.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesCheckboxTree.java @@ -319,13 +319,55 @@ public class PostfixTemplatesCheckboxTree extends CheckboxTree implements Dispos lastPathComponent.setTemplate(newTemplate); } myModel.nodeStructureChanged(lastPathComponent); - + //update before /after panel selectionChanged(); } } } + public boolean canDuplicateSelectedTemplate() { + TreePath[] selectionPaths = getSelectionModel().getSelectionPaths(); + if (!(selectionPaths == null || selectionPaths.length <= 1)) { + return false; + } + PostfixTemplate selectedTemplate = getSelectedTemplate(); + if (!isEditable(selectedTemplate)) { + return false; + } + PostfixTemplateProvider provider = selectedTemplate.getProvider(); + return provider != null && provider.createEditor(selectedTemplate) != null; + } + + public void duplicateSelectedTemplate() { + TreePath path = getSelectionModel().getSelectionPath(); + Object lastPathComponent = path.getLastPathComponent(); + if (lastPathComponent instanceof PostfixTemplateCheckedTreeNode) { + PostfixTemplate template = ((PostfixTemplateCheckedTreeNode)lastPathComponent).getTemplate(); + PostfixTemplateProvider provider = ((PostfixTemplateCheckedTreeNode)lastPathComponent).getTemplateProvider(); + String languageId = myProviderToLanguage.get(provider); + if (isEditable(template) && languageId != null) { + PostfixTemplate templateToEdit = template instanceof PostfixChangedBuiltinTemplate + ? ((PostfixChangedBuiltinTemplate)template).getDelegate() + : template; + PostfixTemplateEditor editor = provider.createEditor(templateToEdit); + if (editor == null) return; + + String providerName = StringUtil.notNullize(provider.getPresentableName()); + PostfixEditTemplateDialog dialog = new PostfixEditTemplateDialog(this, editor, providerName, templateToEdit); + if (dialog.showAndGet()) { + String templateKey = dialog.getTemplateName(); + PostfixTemplate newTemplate = editor.createTemplate(PostfixTemplatesUtils.generateTemplateId(templateKey, provider), templateKey); + PostfixTemplateCheckedTreeNode createdNode = new PostfixTemplateCheckedTreeNode(newTemplate, provider, true); + DefaultMutableTreeNode languageNode = findOrCreateLanguageNode(languageId); + languageNode.insert(createdNode, languageNode.getIndex((PostfixTemplateCheckedTreeNode)lastPathComponent) + 1); + myModel.nodeStructureChanged(languageNode); + TreeUtil.selectNode(this, createdNode); + } + } + } + } + public boolean canRemoveSelectedTemplates() { TreePath[] paths = getSelectionModel().getSelectionPaths(); if (paths == null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java index 7f7faadabe52..c42e9f5f017f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixTemplatesConfigurable.java @@ -10,15 +10,19 @@ import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateProvider; import com.intellij.codeInsight.template.postfix.templates.PostfixTemplatesUtils; import com.intellij.lang.LanguageExtensionPoint; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.Disposer; +import com.intellij.ui.AnActionButton; import com.intellij.ui.GuiUtils; import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.components.JBCheckBox; import com.intellij.util.Alarm; +import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.Nls; @@ -101,12 +105,32 @@ public class PostfixTemplatesConfigurable implements SearchableConfigurable, Edi .setEditActionUpdater(e -> myCheckboxTree.canEditSelectedTemplate()) .setEditAction(button -> myCheckboxTree.editSelectedTemplate()) .setRemoveActionUpdater(e -> myCheckboxTree.canRemoveSelectedTemplates()) - .setRemoveAction(button -> myCheckboxTree.removeSelectedTemplates()).createPanel()); + .setRemoveAction(button -> myCheckboxTree.removeSelectedTemplates()) + .addExtraAction(duplicateAction()) + .createPanel()); myTemplatesTreeContainer.setLayout(new BorderLayout()); myTemplatesTreeContainer.add(panel); } + private AnActionButton duplicateAction() { + AnActionButton button = new AnActionButton("Duplicate", PlatformIcons.COPY_ICON) { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + if (myCheckboxTree != null) { + myCheckboxTree.duplicateSelectedTemplate(); + } + } + + @Override + public void updateButton(AnActionEvent e) { + e.getPresentation().setEnabled(myCheckboxTree != null && myCheckboxTree.canDuplicateSelectedTemplate()); + } + }; + button.registerCustomShortcutSet(CommonShortcuts.getDuplicate(), myCheckboxTree, myCheckboxTree); + return button; + } + private void resetDescriptionPanel() { if (null != myCheckboxTree && null != myInnerPostfixDescriptionPanel) { myInnerPostfixDescriptionPanel.reset(PostfixTemplateMetaData.createMetaData(myCheckboxTree.getSelectedTemplate()));