blob: 6b48fdf19677eb9f66bc054cd84028224efaab4e [file] [log] [blame]
/*
* User: anna
* Date: 29-Jan-2007
*/
package com.intellij.codeInspection.ui.actions;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.codeInspection.ui.InspectionTreeNode;
import com.intellij.codeInspection.ui.ProblemDescriptionNode;
import com.intellij.codeInspection.ui.RefElementNode;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashSet;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.util.Set;
public class SuppressActionWrapper extends ActionGroup {
private final Project myProject;
private final InspectionManagerEx myManager;
private final Set<InspectionTreeNode> myNodesToSuppress = new HashSet<InspectionTreeNode>();
private final InspectionToolWrapper myToolWrapper;
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.actions.SuppressActionWrapper");
public SuppressActionWrapper(@NotNull final Project project,
@NotNull final InspectionToolWrapper toolWrapper,
@NotNull final TreePath[] paths) {
super(InspectionsBundle.message("suppress.inspection.problem"), false);
myProject = project;
myManager = (InspectionManagerEx)InspectionManager.getInstance(myProject);
for (TreePath path : paths) {
final Object node = path.getLastPathComponent();
if (!(node instanceof TreeNode)) continue;
TreeUtil.traverse((TreeNode)node, new TreeUtil.Traverse() {
@Override
public boolean accept(final Object node) { //fetch leaves
final InspectionTreeNode n = (InspectionTreeNode)node;
if (n.isLeaf()) {
myNodesToSuppress.add(n);
}
return true;
}
});
}
myToolWrapper = toolWrapper;
}
@Override
@NotNull
public SuppressTreeAction[] getChildren(@Nullable final AnActionEvent e) {
final SuppressIntentionAction[] suppressActions = InspectionManagerEx.getSuppressActions(myToolWrapper.getTool());
if (suppressActions == null || suppressActions.length == 0) return new SuppressTreeAction[0];
final SuppressTreeAction[] actions = new SuppressTreeAction[suppressActions.length];
for (int i = 0; i < suppressActions.length; i++) {
final SuppressIntentionAction suppressAction = suppressActions[i];
actions[i] = new SuppressTreeAction(suppressAction);
}
return actions;
}
private boolean suppress(final PsiElement element,
final CommonProblemDescriptor descriptor,
final SuppressIntentionAction action,
final RefEntity refEntity) {
final PsiModificationTracker tracker = PsiManager.getInstance(myProject).getModificationTracker();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
try {
final long startModificationCount = tracker.getModificationCount();
PsiElement container = null;
if (action instanceof SuppressIntentionActionFromFix) {
container = ((SuppressIntentionActionFromFix)action).getContainer(element);
}
if (container == null) {
container = element;
}
if (action.isAvailable(myProject, null, element)) {
action.invoke(myProject, null, element);
}
if (startModificationCount != tracker.getModificationCount()) {
final Set<GlobalInspectionContextImpl> globalInspectionContexts = myManager.getRunningContexts();
for (GlobalInspectionContextImpl context : globalInspectionContexts) {
context.ignoreElement(myToolWrapper.getTool(), container);
if (descriptor != null) {
context.getPresentation(myToolWrapper).ignoreCurrentElementProblem(refEntity, descriptor);
}
}
}
}
catch (IncorrectOperationException e1) {
LOG.error(e1);
}
}
});
return true;
}
@Override
public void update(final AnActionEvent e) {
super.update(e);
e.getPresentation().setEnabled(InspectionManagerEx.getSuppressActions(myToolWrapper.getTool()) != null);
}
private static Pair<PsiElement, CommonProblemDescriptor> getContentToSuppress(InspectionTreeNode node) {
RefElement refElement = null;
CommonProblemDescriptor descriptor = null;
if (node instanceof RefElementNode) {
final RefElementNode elementNode = (RefElementNode)node;
final RefEntity element = elementNode.getElement();
refElement = element instanceof RefElement ? (RefElement)element : null;
descriptor = elementNode.getProblem();
}
else if (node instanceof ProblemDescriptionNode) {
final ProblemDescriptionNode descriptionNode = (ProblemDescriptionNode)node;
final RefEntity element = descriptionNode.getElement();
refElement = element instanceof RefElement ? (RefElement)element : null;
descriptor = descriptionNode.getDescriptor();
}
PsiElement element = descriptor instanceof ProblemDescriptor ? ((ProblemDescriptor)descriptor).getPsiElement() : refElement != null ? refElement.getElement() : null;
return Pair.create(element, descriptor);
}
public class SuppressTreeAction extends AnAction {
private final SuppressIntentionAction mySuppressAction;
public SuppressTreeAction(final SuppressIntentionAction suppressAction) {
super(suppressAction.getText());
mySuppressAction = suppressAction;
}
@Override
public void actionPerformed(final AnActionEvent e) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
@Override
public void run() {
for (InspectionTreeNode node : myNodesToSuppress) {
final Pair<PsiElement, CommonProblemDescriptor> content = getContentToSuppress(node);
if (content.first == null) break;
final PsiElement element = content.first;
RefEntity refEntity = null;
if (node instanceof RefElementNode) {
refEntity = ((RefElementNode)node).getElement();
} else if (node instanceof ProblemDescriptionNode) {
refEntity = ((ProblemDescriptionNode)node).getElement();
}
if (!suppress(element, content.second, mySuppressAction, refEntity)) break;
}
final Set<GlobalInspectionContextImpl> globalInspectionContexts = myManager.getRunningContexts();
for (GlobalInspectionContextImpl context : globalInspectionContexts) {
context.refreshViews();
}
CommandProcessor.getInstance().markCurrentCommandAsGlobal(myProject);
}
}, getTemplatePresentation().getText(), null);
}
});
}
@Override
public void update(final AnActionEvent e) {
super.update(e);
if (!isAvailable()) e.getPresentation().setVisible(false);
}
public boolean isAvailable() {
for (InspectionTreeNode node : myNodesToSuppress) {
final Pair<PsiElement, CommonProblemDescriptor> content = getContentToSuppress(node);
if (content.first == null) continue;
final PsiElement element = content.first;
if (mySuppressAction.isAvailable(myProject, null, element)) {
return true;
}
}
return false;
}
}
}