hide actions from popups, leave access through shortcut (IDEA-141474, IDEA-77602)

This commit is contained in:
Anna Kozlova
2015-06-16 18:18:42 +03:00
parent 4b972e9f58
commit 4ce6411664
18 changed files with 233 additions and 48 deletions
@@ -91,13 +91,7 @@ public class GenerateEqualsHandler extends GenerateMembersHandlerBase {
return null;
}
}
boolean hasNonStaticFields = false;
for (PsiField field : aClass.getFields()) {
if (!field.hasModifierProperty(PsiModifier.STATIC)) {
hasNonStaticFields = true;
break;
}
}
boolean hasNonStaticFields = hasNonStaticFields(aClass);
if (!hasNonStaticFields) {
HintManager.getInstance().showErrorHint(editor, "No fields to include in equals/hashCode have been found");
return null;
@@ -113,6 +107,20 @@ public class GenerateEqualsHandler extends GenerateMembersHandlerBase {
return DUMMY_RESULT;
}
private static boolean hasNonStaticFields(PsiClass aClass) {
for (PsiField field : aClass.getFields()) {
if (!field.hasModifierProperty(PsiModifier.STATIC)) {
return true;
}
}
return false;
}
@Override
protected boolean hasMembers(@NotNull PsiClass aClass) {
return hasNonStaticFields(aClass);
}
@Override
@NotNull
protected List<? extends GenerationInfo> generateMemberPrototypes(PsiClass aClass, ClassMember[] originalMembers) throws IncorrectOperationException {
@@ -74,6 +74,11 @@ public abstract class GenerateGetterSetterHandlerBase extends GenerateMembersHan
super(chooserTitle);
}
@Override
protected boolean hasMembers(@NotNull PsiClass aClass) {
return !GenerateAccessorProviderRegistrar.getEncapsulatableClassMembers(aClass).isEmpty();
}
@Override
protected String getHelpId() {
return "Getter and Setter Templates Dialog";
@@ -23,6 +23,8 @@ import com.intellij.codeInsight.template.TemplateEditingAdapter;
import com.intellij.codeInsight.template.TemplateManager;
import com.intellij.codeInspection.ex.GlobalInspectionContextBase;
import com.intellij.ide.util.MemberChooser;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
@@ -47,7 +49,7 @@ import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
public abstract class GenerateMembersHandlerBase implements CodeInsightActionHandler {
public abstract class GenerateMembersHandlerBase implements CodeInsightActionHandler, ContextAwareActionHandler {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.GenerateMembersHandlerBase");
private final String myChooserTitle;
@@ -57,6 +59,16 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan
myChooserTitle = chooserTitle;
}
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
final PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, false);
return aClass != null && hasMembers(aClass);
}
protected boolean hasMembers(@NotNull PsiClass aClass) {
return true;
}
@Override
public final void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
if (!CodeInsightUtilBase.prepareEditorForWrite(editor)) return;
@@ -16,7 +16,9 @@
package com.intellij.codeInsight.generation;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.lang.LanguageCodeInsightActionHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
@@ -29,15 +31,14 @@ import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
public class JavaImplementMethodsHandler implements LanguageCodeInsightActionHandler {
public class JavaImplementMethodsHandler implements ContextAwareActionHandler, LanguageCodeInsightActionHandler {
@Override
public boolean isValidFor(final Editor editor, final PsiFile file) {
if (!(file instanceof PsiJavaFile) && !(file instanceof PsiCodeFragment)) {
return false;
}
PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, PsiUtil.isLanguageLevel8OrHigher(file));
return aClass != null && !OverrideImplementUtil.getMethodSignaturesToImplement(aClass).isEmpty();
return OverrideImplementUtil.getContextClass(file.getProject(), editor, file, PsiUtil.isLanguageLevel8OrHigher(file)) != null;
}
@Override
@@ -57,4 +58,10 @@ public class JavaImplementMethodsHandler implements LanguageCodeInsightActionHan
public boolean startInWriteAction() {
return false;
}
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, PsiUtil.isLanguageLevel8OrHigher(file));
return aClass != null && !OverrideImplementUtil.getMethodSignaturesToImplement(aClass).isEmpty();
}
}
@@ -16,7 +16,9 @@
package com.intellij.codeInsight.generation;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.lang.LanguageCodeInsightActionHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
@@ -28,15 +30,14 @@ import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
public class JavaOverrideMethodsHandler implements LanguageCodeInsightActionHandler {
public class JavaOverrideMethodsHandler implements ContextAwareActionHandler, LanguageCodeInsightActionHandler {
@Override
public boolean isValidFor(final Editor editor, final PsiFile file) {
if (!(file instanceof PsiJavaFile) && !(file instanceof PsiCodeFragment)) {
return false;
}
PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, true);
return aClass != null && !OverrideImplementUtil.getMethodSignaturesToOverride(aClass).isEmpty();
return OverrideImplementUtil.getContextClass(file.getProject(), editor, file, true) != null;
}
@Override
@@ -55,4 +56,10 @@ public class JavaOverrideMethodsHandler implements LanguageCodeInsightActionHand
public boolean startInWriteAction() {
return false;
}
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, true);
return aClass != null && !OverrideImplementUtil.getMethodSignaturesToOverride(aClass).isEmpty();
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
@@ -23,6 +24,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.extractMethod.ExtractMethodHandler;
import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
@@ -30,9 +32,15 @@ import org.jetbrains.annotations.TestOnly;
/**
* @author dsl
*/
public abstract class IntroduceHandlerBase implements RefactoringActionHandler {
public abstract class IntroduceHandlerBase implements RefactoringActionHandler, ContextAwareActionHandler {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.IntroduceHandlerBase");
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
final PsiElement[] elements = ExtractMethodHandler.getElements(file.getProject(), editor, file);
return elements != null && elements.length > 0;
}
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
LOG.assertTrue(elements.length >= 1 && elements[0] instanceof PsiExpression, "incorrect invoke() parameters");
final PsiElement tempExpr = elements[0];
@@ -18,6 +18,7 @@ package com.intellij.refactoring.extractMethod;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -56,7 +57,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public class ExtractMethodHandler implements RefactoringActionHandler {
public class ExtractMethodHandler implements RefactoringActionHandler, ContextAwareActionHandler {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractMethod.ExtractMethodHandler");
public static final String REFACTORING_NAME = RefactoringBundle.message("extract.method.title");
@@ -103,10 +104,21 @@ public class ExtractMethodHandler implements RefactoringActionHandler {
}
}
PsiDocumentManager.getInstance(project).commitAllDocuments();
callback.pass(getElements(project, editor, file));
}
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
final PsiElement[] elements = getElements(file.getProject(), editor, file);
return elements != null && elements.length > 0;
}
public static PsiElement[] getElements(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
int startOffset = editor.getSelectionModel().getSelectionStart();
int endOffset = editor.getSelectionModel().getSelectionEnd();
PsiDocumentManager.getInstance(project).commitAllDocuments();
PsiElement[] elements;
PsiExpression expr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset);
@@ -125,7 +137,7 @@ public class ExtractMethodHandler implements RefactoringActionHandler {
}
}
}
callback.pass(elements);
return elements;
}
private static void invokeOnElements(final Project project, final Editor editor, PsiFile file, PsiElement[] elements) {
@@ -20,6 +20,7 @@
*/
package com.intellij.refactoring.extractMethodObject;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -42,7 +43,7 @@ import com.intellij.refactoring.util.duplicates.DuplicatesImpl;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class ExtractMethodObjectHandler implements RefactoringActionHandler {
public class ExtractMethodObjectHandler implements RefactoringActionHandler, ContextAwareActionHandler {
private static final Logger LOG = Logger.getInstance("#" + ExtractMethodObjectHandler.class.getName());
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file, final DataContext dataContext) {
@@ -53,6 +54,12 @@ public class ExtractMethodObjectHandler implements RefactoringActionHandler {
});
}
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
final PsiElement[] elements = ExtractMethodHandler.getElements(file.getProject(), editor, file);
return elements != null && elements.length > 0;
}
private static void invokeOnElements(@NotNull final Project project,
@NotNull final Editor editor,
@NotNull PsiFile file,
@@ -16,10 +16,9 @@
package com.intellij.refactoring.introduceparameterobject;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
@@ -34,12 +33,33 @@ import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import org.jetbrains.annotations.NotNull;
public class IntroduceParameterObjectHandler implements RefactoringActionHandler {
public class IntroduceParameterObjectHandler implements RefactoringActionHandler, ContextAwareActionHandler {
private static final String REFACTORING_NAME = RefactorJBundle.message("introduce.parameter.object");
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
final PsiMethod selectedMethod = getSelectedMethod(editor, file, dataContext);
if (selectedMethod != null) {
final PsiMethod[] deepestSuperMethods = selectedMethod.findDeepestSuperMethods();
return deepestSuperMethods.length > 0 || getErrorMessage(selectedMethod) == null;
}
return false;
}
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE);
PsiMethod selectedMethod = getSelectedMethod(editor, file, dataContext);
if (selectedMethod == null) {
final String message = RefactorJBundle.message("cannot.perform.the.refactoring") +
RefactorJBundle.message("the.caret.should.be.positioned.at.the.name.of.the.method.to.be.refactored");
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.IntroduceParameterObject);
return;
}
invoke(project, selectedMethod, editor);
}
private static PsiMethod getSelectedMethod(Editor editor, PsiFile file, DataContext dataContext) {
final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
PsiMethod selectedMethod = null;
if (element instanceof PsiMethod) {
@@ -63,13 +83,7 @@ public class IntroduceParameterObjectHandler implements RefactoringActionHandler
}
}
}
if (selectedMethod == null) {
final String message = RefactorJBundle.message("cannot.perform.the.refactoring") +
RefactorJBundle.message("the.caret.should.be.positioned.at.the.name.of.the.method.to.be.refactored");
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.IntroduceParameterObject);
return;
}
invoke(project, selectedMethod, editor);
return selectedMethod;
}
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
@@ -87,20 +101,26 @@ public class IntroduceParameterObjectHandler implements RefactoringActionHandler
private static void invoke(final Project project, final PsiMethod selectedMethod, Editor editor) {
PsiMethod newMethod = SuperMethodWarningUtil.checkSuperMethod(selectedMethod, RefactoringBundle.message("to.refactor"));
if (newMethod == null) return;
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, newMethod)) return;
final PsiParameter[] parameters = newMethod.getParameterList().getParameters();
if (parameters.length == 0) {
final String message =
RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message("method.selected.has.no.parameters");
final String message = getErrorMessage(newMethod);
if (message != null) {
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.IntroduceParameterObject);
return;
}
if (newMethod instanceof PsiCompiledElement) {
CommonRefactoringUtil.showErrorHint(project, editor, RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message(
"the.selected.method.cannot.be.wrapped.because.it.is.defined.in.a.non.project.class"), REFACTORING_NAME, HelpID.IntroduceParameterObject);
return;
}
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, newMethod)) return;
new IntroduceParameterObjectDialog(newMethod).show();
}
private static String getErrorMessage(PsiMethod newMethod) {
final PsiParameter[] parameters = newMethod.getParameterList().getParameters();
if (parameters.length == 0) {
return RefactorJBundle.message("cannot.perform.the.refactoring") +
RefactorJBundle.message("method.selected.has.no.parameters");
}
if (newMethod instanceof PsiCompiledElement) {
return RefactorJBundle.message("cannot.perform.the.refactoring") +
RefactorJBundle.message("the.selected.method.cannot.be.wrapped.because.it.is.defined.in.a.non.project.class");
}
return null;
}
}
@@ -20,6 +20,7 @@ import com.intellij.analysis.AnalysisUIOptions;
import com.intellij.analysis.BaseAnalysisActionDialog;
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
@@ -55,10 +56,16 @@ import java.util.*;
/**
* @author dsl
*/
public class MethodDuplicatesHandler implements RefactoringActionHandler {
public class MethodDuplicatesHandler implements RefactoringActionHandler, ContextAwareActionHandler {
public static final String REFACTORING_NAME = RefactoringBundle.message("replace.method.code.duplicates.title");
private static final Logger LOG = Logger.getInstance("#" + MethodDuplicatesHandler.class.getName());
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
return getCannotRefactorMessage(PsiTreeUtil.getParentOfType(element, PsiMember.class)) == null;
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) {
final int offset = editor.getCaretModel().getOffset();
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.PsiMethodMember;
import com.intellij.codeInsight.intention.impl.ImplementAbstractMethodHandler;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -29,6 +30,7 @@ import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.MapDataContext;
import com.intellij.util.FunctionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
@@ -134,7 +136,9 @@ public class OverrideImplement15Test extends LightCodeInsightTestCase {
PsiElement context = getFile().findElementAt(offset);
final PsiClass aClass = PsiTreeUtil.getParentOfType(context, PsiClass.class);
assertTrue(aClass != null && aClass.isAnnotationType());
assertFalse(new JavaOverrideMethodsHandler().isValidFor(getEditor(), getFile()));
final JavaOverrideMethodsHandler handler = new JavaOverrideMethodsHandler();
assertTrue(handler.isValidFor(getEditor(), getFile()));
assertFalse(handler.isAvailableForQuickList(getEditor(), getFile(), new MapDataContext()));
}
private void doTest(boolean copyJavadoc) { doTest(copyJavadoc, null); }
@@ -18,8 +18,10 @@ package com.intellij.codeInsight.generation.actions;
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.actions.CodeInsightAction;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -34,6 +36,19 @@ public class BaseGenerateAction extends CodeInsightAction implements GenerateAct
myHandler = handler;
}
@Override
protected void update(@NotNull Presentation presentation,
@NotNull Project project,
@NotNull Editor editor,
@NotNull PsiFile file,
@NotNull DataContext dataContext,
@Nullable String actionPlace) {
super.update(presentation, project, editor, file, dataContext, actionPlace);
if (myHandler instanceof ContextAwareActionHandler && presentation.isEnabled()) {
presentation.setEnabled(((ContextAwareActionHandler)myHandler).isAvailableForQuickList(editor, file, dataContext));
}
}
@Nullable
public AnAction createEditTemplateAction(DataContext dataContext) {
return null;
@@ -16,11 +16,15 @@
package com.intellij.codeInsight;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* See {@link ContextAwareActionHandler} to hide action from popups but allow access by shortcut, main menu or find.
*/
public interface CodeInsightActionHandler {
void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file);
@@ -82,7 +82,8 @@ public abstract class CodeInsightAction extends AnAction {
return;
}
Editor editor = getEditor(e.getDataContext(), project);
final DataContext dataContext = e.getDataContext();
Editor editor = getEditor(dataContext, project);
if (editor == null) {
presentation.setEnabled(false);
return;
@@ -94,13 +95,18 @@ public abstract class CodeInsightAction extends AnAction {
return;
}
update(presentation, project, editor, file);
update(presentation, project, editor, file, dataContext, e.getPlace());
}
protected void update(@NotNull Presentation presentation, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
presentation.setEnabled(isValidForFile(project, editor, file));
}
protected void update(@NotNull Presentation presentation, @NotNull Project project,
@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext, @Nullable String actionPlace) {
update(presentation, project, editor, file);
}
protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
return true;
}
@@ -0,0 +1,36 @@
/*
* Copyright 2000-2015 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.lang;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
public interface ContextAwareActionHandler {
/**
* Handlers could provide useful hints when they are actually not available, e.g.
* 'No methods to implement', 'Selected block should represent ...', 'Caret should be positioned at the name of ...', etc.
* At the same time, when the action is invoked through refactorings quick list popup,
* generate popup or in another manner but not through main menu (shortcut or find action are treated the same),
* it's better to hide the action: it would pollute menu with one more choice but can't do anything.
*
* @return It's assumed that handler is valid for file. Still should be lightweight, because is invoked from action update.
* false - if action won't proceed
*/
boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext);
}
@@ -17,10 +17,13 @@
package com.intellij.codeInsight.generation.actions;
import com.intellij.codeInsight.actions.BaseCodeInsightAction;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageCodeInsightActionHandler;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -49,13 +52,17 @@ public abstract class PresentableActionHandlerBasedAction extends BaseCodeInsigh
}
@Override
protected void update(@NotNull Presentation presentation, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
protected void update(@NotNull Presentation presentation, @NotNull Project project,
@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext, @Nullable String actionPlace) {
// avoid evaluating isValidFor several times unnecessary
LanguageCodeInsightActionHandler handler = getValidHandler(editor, file);
presentation.setEnabled(handler != null);
if (handler instanceof ContextAwareActionHandler && !ActionPlaces.isMainMenuOrActionSearch(actionPlace)) {
presentation.setVisible(((ContextAwareActionHandler)handler).isAvailableForQuickList(editor, file, dataContext));
}
if (handler instanceof PresentableLanguageCodeInsightActionHandler) {
if (presentation.isVisible() && handler instanceof PresentableLanguageCodeInsightActionHandler) {
((PresentableLanguageCodeInsightActionHandler)handler).update(editor, file, presentation);
}
}
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.lookup.LookupEx;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.ide.IdeEventQueue;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.command.CommandProcessor;
@@ -64,7 +65,18 @@ public abstract class BaseRefactoringAction extends AnAction {
}
protected boolean hasAvailableHandler(@NotNull DataContext dataContext) {
return getHandler(dataContext) != null;
final RefactoringActionHandler handler = getHandler(dataContext);
if (handler != null) {
if (handler instanceof ContextAwareActionHandler) {
final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
final PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext);
if (editor != null && file != null && !((ContextAwareActionHandler)handler).isAvailableForQuickList(editor, file, dataContext)) {
return false;
}
}
return true;
}
return false;
}
@Nullable
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.actions;
import com.intellij.lang.ContextAwareActionHandler;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageRefactoringSupport;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
@@ -90,7 +91,14 @@ public class ChangeSignatureAction extends BasePlatformRefactoringAction {
@Nullable
@Override
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider, final PsiElement element) {
return new RefactoringActionHandler() {
abstract class ContextAwareChangeSignatureHandler implements RefactoringActionHandler, ContextAwareActionHandler {}
return new ContextAwareChangeSignatureHandler() {
@Override
public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) {
return findTargetMember(element) != null;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);