mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-100392 Allow file template configuration from generate popup
This commit is contained in:
+87
-39
@@ -22,17 +22,23 @@ import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.codeInsight.generation.PsiGenerationInfo;
|
||||
import com.intellij.codeInsight.generation.actions.BaseGenerateAction;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
|
||||
import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -48,13 +54,46 @@ public class BaseGenerateTestSupportMethodAction extends BaseGenerateAction {
|
||||
super(new MyHandler(methodKind));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AnAction createEditTemplateAction(DataContext dataContext) {
|
||||
final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
|
||||
final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
|
||||
final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
|
||||
final PsiClass targetClass = editor == null || file == null ? null : getTargetClass(editor, file);
|
||||
if (targetClass != null) {
|
||||
final List<TestFramework> frameworks = TestIntegrationUtils.findSuitableFrameworks(targetClass);
|
||||
final TestIntegrationUtils.MethodKind methodKind = ((MyHandler)getHandler()).myMethodKind;
|
||||
if (!frameworks.isEmpty()) {
|
||||
return new AnAction("Edit Template") {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
chooseAndPerform(editor, frameworks, new Consumer<TestFramework>() {
|
||||
@Override
|
||||
public void consume(TestFramework framework) {
|
||||
final FileTemplateDescriptor descriptor = methodKind.getFileTemplateDescriptor(framework);
|
||||
if (descriptor != null) {
|
||||
final String fileName = descriptor.getFileName();
|
||||
AllFileTemplatesConfigurable.editCodeTemplate(FileUtil.getNameWithoutExtension(fileName), project);
|
||||
} else {
|
||||
HintManager.getInstance().showErrorHint(editor, "No template found for " + framework.getName() + ":" + BaseGenerateTestSupportMethodAction.this.getTemplatePresentation().getText());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiClass getTargetClass(Editor editor, PsiFile file) {
|
||||
return findTargetClass(editor, file);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass findTargetClass(Editor editor, PsiFile file) {
|
||||
private static PsiClass findTargetClass(@NotNull Editor editor, @NotNull PsiFile file) {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
return element == null ? null : TestIntegrationUtils.findOuterClass(element);
|
||||
@@ -86,6 +125,47 @@ public class BaseGenerateTestSupportMethodAction extends BaseGenerateAction {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void chooseAndPerform(Editor editor, List<TestFramework> frameworks, final Consumer<TestFramework> consumer) {
|
||||
if (frameworks.size() == 1) {
|
||||
consumer.consume(frameworks.get(0));
|
||||
return;
|
||||
}
|
||||
|
||||
final JList list = new JBList(frameworks.toArray(new TestFramework[frameworks.size()]));
|
||||
list.setCellRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
Component result = super.getListCellRendererComponent(list, "", index, isSelected, cellHasFocus);
|
||||
if (value == null) return result;
|
||||
TestFramework framework = (TestFramework)value;
|
||||
|
||||
setIcon(framework.getIcon());
|
||||
setText(framework.getName());
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
PopupChooserBuilder builder = new PopupChooserBuilder(list);
|
||||
builder.setFilteringEnabled(new Function<Object, String>() {
|
||||
@Override
|
||||
public String fun(Object o) {
|
||||
return ((TestFramework)o).getName();
|
||||
}
|
||||
});
|
||||
|
||||
builder
|
||||
.setTitle("Choose Framework")
|
||||
.setItemChoosenCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
consumer.consume((TestFramework)list.getSelectedValue());
|
||||
}
|
||||
})
|
||||
.setMovable(true)
|
||||
.createPopup().showInBestPositionFor(editor);
|
||||
}
|
||||
|
||||
private static class MyHandler implements CodeInsightActionHandler {
|
||||
private TestIntegrationUtils.MethodKind myMethodKind;
|
||||
@@ -98,50 +178,18 @@ public class BaseGenerateTestSupportMethodAction extends BaseGenerateAction {
|
||||
final PsiClass targetClass = findTargetClass(editor, file);
|
||||
final List<TestFramework> frameworks = TestIntegrationUtils.findSuitableFrameworks(targetClass);
|
||||
if (frameworks.isEmpty()) return;
|
||||
|
||||
if (frameworks.size() == 1) {
|
||||
doGenerate(editor, file, targetClass, frameworks.get(0));
|
||||
return;
|
||||
}
|
||||
|
||||
final JList list = new JBList(frameworks.toArray(new TestFramework[frameworks.size()]));
|
||||
list.setCellRenderer(new DefaultListCellRenderer() {
|
||||
final Consumer<TestFramework> consumer = new Consumer<TestFramework>() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
Component result = super.getListCellRendererComponent(list, "", index, isSelected, cellHasFocus);
|
||||
if (value == null) return result;
|
||||
TestFramework framework = (TestFramework)value;
|
||||
|
||||
setIcon(framework.getIcon());
|
||||
setText(framework.getName());
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
TestFramework selected = (TestFramework)list.getSelectedValue();
|
||||
if (selected == null) return;
|
||||
doGenerate(editor, file, targetClass, selected);
|
||||
public void consume(TestFramework framework) {
|
||||
if (framework == null) return;
|
||||
doGenerate(editor, file, targetClass, framework);
|
||||
}
|
||||
};
|
||||
|
||||
PopupChooserBuilder builder = new PopupChooserBuilder(list);
|
||||
builder.setFilteringEnabled(new Function<Object, String>() {
|
||||
@Override
|
||||
public String fun(Object o) {
|
||||
return ((TestFramework)o).getName();
|
||||
}
|
||||
});
|
||||
|
||||
builder
|
||||
.setTitle("Choose Framework")
|
||||
.setItemChoosenCallback(runnable)
|
||||
.setMovable(true)
|
||||
.createPopup().showInBestPositionFor(editor);
|
||||
chooseAndPerform(editor, frameworks, consumer);
|
||||
}
|
||||
|
||||
|
||||
private void doGenerate(final Editor editor, final PsiFile file, final PsiClass targetClass, final TestFramework framework) {
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(file)) return;
|
||||
|
||||
|
||||
+8
-1
@@ -18,6 +18,8 @@ package com.intellij.codeInsight.generation.actions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.actions.CodeInsightAction;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
@@ -25,13 +27,18 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BaseGenerateAction extends CodeInsightAction {
|
||||
public class BaseGenerateAction extends CodeInsightAction implements GenerateActionPopupTemplateInjector {
|
||||
private final CodeInsightActionHandler myHandler;
|
||||
|
||||
public BaseGenerateAction(CodeInsightActionHandler handler) {
|
||||
myHandler = handler;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AnAction createEditTemplateAction(DataContext dataContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected final CodeInsightActionHandler getHandler() {
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.generation.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Generate action could provide an action to edit corresponding file template. It would appear then in the subMenu of the Generate... popup
|
||||
*/
|
||||
public interface GenerateActionPopupTemplateInjector {
|
||||
@Nullable
|
||||
AnAction createEditTemplateAction(DataContext dataContext);
|
||||
}
|
||||
+51
-1
@@ -24,6 +24,8 @@ import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.ListPopup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class GenerateAction extends DumbAwareAction implements PreloadableAction {
|
||||
@Override
|
||||
@@ -33,7 +35,7 @@ public class GenerateAction extends DumbAwareAction implements PreloadableAction
|
||||
final ListPopup popup =
|
||||
JBPopupFactory.getInstance().createActionGroupPopup(
|
||||
CodeInsightBundle.message("generate.list.popup.title"),
|
||||
getGroup(),
|
||||
wrapGroup(getGroup(), dataContext),
|
||||
dataContext,
|
||||
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
|
||||
false);
|
||||
@@ -65,8 +67,56 @@ public class GenerateAction extends DumbAwareAction implements PreloadableAction
|
||||
return (DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_GENERATE);
|
||||
}
|
||||
|
||||
private static DefaultActionGroup wrapGroup(DefaultActionGroup actionGroup, DataContext dataContext) {
|
||||
final DefaultActionGroup copy = new DefaultActionGroup();
|
||||
for (final AnAction action : actionGroup.getChildren(null)) {
|
||||
if (action instanceof GenerateActionPopupTemplateInjector) {
|
||||
final AnAction editTemplateAction = ((GenerateActionPopupTemplateInjector)action).createEditTemplateAction(dataContext);
|
||||
if (editTemplateAction != null) {
|
||||
copy.add(new GenerateWrappingGroup(action, editTemplateAction));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (action instanceof DefaultActionGroup) {
|
||||
copy.add(wrapGroup((DefaultActionGroup)action, dataContext));
|
||||
} else {
|
||||
copy.add(action);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preload() {
|
||||
((ActionManagerImpl) ActionManager.getInstance()).preloadActionGroup(IdeActions.GROUP_GENERATE);
|
||||
}
|
||||
|
||||
private static class GenerateWrappingGroup extends ActionGroup {
|
||||
|
||||
private final AnAction myAction;
|
||||
private final AnAction myEditTemplateAction;
|
||||
|
||||
public GenerateWrappingGroup(AnAction action, AnAction editTemplateAction) {
|
||||
myAction = action;
|
||||
myEditTemplateAction = editTemplateAction;
|
||||
copyFrom(action);
|
||||
setPopup(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBePerformed(DataContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public AnAction[] getChildren(@Nullable AnActionEvent e) {
|
||||
return new AnAction[] {myEditTemplateAction};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
myAction.actionPerformed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -28,6 +28,8 @@ import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
@@ -630,4 +632,21 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con
|
||||
public Runnable enableSearch(String option) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void editCodeTemplate(@NotNull final String templateId, Project project) {
|
||||
final ShowSettingsUtil util = ShowSettingsUtil.getInstance();
|
||||
final AllFileTemplatesConfigurable configurable = new AllFileTemplatesConfigurable();
|
||||
util.editConfigurable(project, configurable, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
configurable.myTabbedPane.setSelectedIndex(ArrayUtil.indexOf(configurable.myTabs, configurable.myCodeTemplatesList));
|
||||
for (FileTemplate template : configurable.myCodeTemplatesList.getTemplates()) {
|
||||
if (Comparing.equal(templateId, template.getName())) {
|
||||
configurable.myCodeTemplatesList.selectTemplate(template);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user