/* * Copyright 2000-2009 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.codeInspection.ui; import com.intellij.CommonBundle; import com.intellij.analysis.AnalysisScope; import com.intellij.analysis.AnalysisUIOptions; import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInsight.highlighting.HighlightManager; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.actions.ExportHTMLAction; import com.intellij.codeInspection.ui.actions.InspectionsOptionsToolbarAction; import com.intellij.codeInspection.ui.actions.InvokeQuickFixAction; import com.intellij.icons.AllIcons; import com.intellij.ide.*; import com.intellij.ide.actions.ContextHelpAction; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.pom.Navigatable; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.*; import com.intellij.util.OpenSourceUtil; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.InputEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.*; import java.util.List; /** * @author max */ public class InspectionResultsView extends JPanel implements Disposable, OccurenceNavigator, DataProvider { public static final DataKey<InspectionResultsView> DATA_KEY = DataKey.create("inspectionView"); private final Project myProject; private InspectionTree myTree; private final Browser myBrowser; private Map<HighlightDisplayLevel, Map<String, InspectionGroupNode>> myGroups = null; private OccurenceNavigator myOccurenceNavigator; private InspectionProfile myInspectionProfile; private final AnalysisScope myScope; @NonNls private static final String HELP_ID = "reference.toolWindows.inspections"; private final Map<HighlightDisplayLevel, InspectionSeverityGroupNode> mySeverityGroupNodes = new TreeMap<HighlightDisplayLevel, InspectionSeverityGroupNode>(new Comparator<HighlightDisplayLevel>() { @Override public int compare(HighlightDisplayLevel o1, HighlightDisplayLevel o2) { final int severityDiff = o1.getSeverity().compareTo(o2.getSeverity()); if (severityDiff == 0) { return o1.toString().compareTo(o2.toString()); } return severityDiff; } }); private final Splitter mySplitter; @NotNull private final GlobalInspectionContextImpl myGlobalInspectionContext; private boolean myRerun = false; @NotNull private final InspectionRVContentProvider myProvider; private AnAction myIncludeAction; private AnAction myExcludeAction; public InspectionResultsView(@NotNull final Project project, final InspectionProfile inspectionProfile, @NotNull AnalysisScope scope, @NotNull GlobalInspectionContextImpl globalInspectionContext, @NotNull InspectionRVContentProvider provider) { setLayout(new BorderLayout()); myProject = project; myInspectionProfile = inspectionProfile; myScope = scope; myGlobalInspectionContext = globalInspectionContext; myProvider = provider; myTree = new InspectionTree(project, globalInspectionContext); initTreeListeners(); myOccurenceNavigator = initOccurenceNavigator(); myBrowser = new Browser(this); mySplitter = new Splitter(false, AnalysisUIOptions.getInstance(myProject).SPLITTER_PROPORTION); mySplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myTree, SideBorder.LEFT | SideBorder.RIGHT)); mySplitter.setSecondComponent(myBrowser); mySplitter.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (Splitter.PROP_PROPORTION.equals(evt.getPropertyName())) { myGlobalInspectionContext.setSplitterProportion(((Float)evt.getNewValue()).floatValue()); } } }); add(mySplitter, BorderLayout.CENTER); myBrowser.addClickListener(new Browser.ClickListener() { @Override public void referenceClicked(final Browser.ClickEvent e) { if (e.getEventType() == Browser.ClickEvent.REF_ELEMENT) { final RefElement refElement = e.getClickedElement(); final OpenFileDescriptor descriptor = getOpenFileDescriptor(refElement); if (descriptor != null) { FileEditorManager.getInstance(project).openTextEditor(descriptor, false); } } else if (e.getEventType() == Browser.ClickEvent.FILE_OFFSET) { final VirtualFile file = e.getFile(); final OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file, e.getStartOffset()); final Editor editor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true); if (editor != null) { final TextAttributes selectionAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); HighlightManager.getInstance(project) .addRangeHighlight(editor, e.getStartOffset(), e.getEndOffset(), selectionAttributes, true, null); } } } }); createActionsToolbar(); } private void initTreeListeners() { myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(TreeSelectionEvent e) { syncBrowser(); if (isAutoScrollMode()) { OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(InspectionResultsView.this), false); } } }); new DoubleClickListener() { @Override protected boolean onDoubleClick(MouseEvent e) { OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(InspectionResultsView.this), true); return true; } }.installOn(myTree); myTree.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(InspectionResultsView.this), false); } } }); myTree.addMouseListener(new PopupHandler() { @Override public void invokePopup(Component comp, int x, int y) { popupInvoked(comp, x, y); } }); SmartExpander.installOn(myTree); } private OccurenceNavigatorSupport initOccurenceNavigator(){ return new OccurenceNavigatorSupport(myTree) { @Override @Nullable protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) { if (node instanceof RefElementNode) { final RefElementNode refNode = (RefElementNode)node; if (refNode.hasDescriptorsUnder()) return null; final RefEntity element = refNode.getElement(); if (element == null || !element.isValid()) return null; final CommonProblemDescriptor problem = refNode.getProblem(); if (problem != null) { return navigate(problem); } if (element instanceof RefElement) { return getOpenFileDescriptor((RefElement)element); } } else if (node instanceof ProblemDescriptionNode) { if (!((ProblemDescriptionNode)node).isValid()) return null; return navigate(((ProblemDescriptionNode)node).getDescriptor()); } return null; } @Nullable private Navigatable navigate(final CommonProblemDescriptor descriptor) { return getSelectedNavigatable(descriptor); } @Override public String getNextOccurenceActionName() { return InspectionsBundle.message("inspection.action.go.next"); } @Override public String getPreviousOccurenceActionName() { return InspectionsBundle.message("inspection.actiongo.prev"); } }; } private void createActionsToolbar() { final JComponent leftActionsToolbar = createLeftActionsToolbar(); final JComponent rightActionsToolbar = createRightActionsToolbar(); JPanel westPanel = new JPanel(new BorderLayout()); westPanel.add(leftActionsToolbar, BorderLayout.WEST); westPanel.add(rightActionsToolbar, BorderLayout.EAST); add(westPanel, BorderLayout.WEST); } @SuppressWarnings({"NonStaticInitializer"}) private JComponent createRightActionsToolbar() { myIncludeAction = new AnAction(InspectionsBundle.message("inspections.result.view.include.action.text")){ { registerCustomShortcutSet(CommonShortcuts.INSERT, myTree); } @Override public void actionPerformed(AnActionEvent e) { ((InspectionTreeNode)myTree.getSelectionPath().getLastPathComponent()).amnesty(); updateView(false); } @Override public void update(final AnActionEvent e) { final TreePath path = myTree.getSelectionPath(); e.getPresentation().setEnabled(path != null && !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS); } }; myExcludeAction = new AnAction(InspectionsBundle.message("inspections.result.view.exclude.action.text")) { { registerCustomShortcutSet(CommonShortcuts.DELETE, myTree); } @Override public void actionPerformed(final AnActionEvent e) { ((InspectionTreeNode)myTree.getSelectionPath().getLastPathComponent()).ignoreElement(); updateView(false); } @Override public void update(final AnActionEvent e) { final TreePath path = myTree.getSelectionPath(); e.getPresentation().setEnabled(path != null); } }; DefaultActionGroup specialGroup = new DefaultActionGroup(); specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupBySeverityAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupByDirectoryAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createFilterResolvedItemsAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createShowOutdatedProblemsAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createShowDiffOnlyAction(this)); specialGroup.add(new EditSettingsAction()); specialGroup.add(new InvokeQuickFixAction(this)); specialGroup.add(new InspectionsOptionsToolbarAction(this)); return createToolbar(specialGroup); } private JComponent createLeftActionsToolbar() { final CommonActionsManager actionsManager = CommonActionsManager.getInstance(); DefaultActionGroup group = new DefaultActionGroup(); group.add(new RerunAction(this)); group.add(new CloseAction()); final TreeExpander treeExpander = new TreeExpander() { @Override public void expandAll() { TreeUtil.expandAll(myTree); } @Override public boolean canExpand() { return true; } @Override public void collapseAll() { TreeUtil.collapseAll(myTree, 0); } @Override public boolean canCollapse() { return true; } }; group.add(actionsManager.createExpandAllAction(treeExpander, myTree)); group.add(actionsManager.createCollapseAllAction(treeExpander, myTree)); group.add(actionsManager.createPrevOccurenceAction(getOccurenceNavigator())); group.add(actionsManager.createNextOccurenceAction(getOccurenceNavigator())); group.add(myGlobalInspectionContext.createToggleAutoscrollAction()); group.add(new ExportHTMLAction(this)); group.add(new ContextHelpAction(HELP_ID)); return createToolbar(group); } private static JComponent createToolbar(final DefaultActionGroup specialGroup) { return ActionManager.getInstance() .createActionToolbar(ActionPlaces.CODE_INSPECTION, specialGroup, false).getComponent(); } @Override public void dispose(){ mySplitter.dispose(); myBrowser.dispose(); myTree = null; myOccurenceNavigator = null; myInspectionProfile = null; } private boolean isAutoScrollMode() { String activeToolWindowId = ToolWindowManager.getInstance(myProject).getActiveToolWindowId(); return myGlobalInspectionContext.getUIOptions().AUTOSCROLL_TO_SOURCE && (activeToolWindowId == null || activeToolWindowId.equals(ToolWindowId.INSPECTION)); } @Nullable private static OpenFileDescriptor getOpenFileDescriptor(final RefElement refElement) { final VirtualFile[] file = new VirtualFile[1]; final int[] offset = new int[1]; ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { PsiElement psiElement = refElement.getElement(); if (psiElement != null) { final PsiFile containingFile = psiElement.getContainingFile(); if (containingFile != null) { file[0] = containingFile.getVirtualFile(); offset[0] = psiElement.getTextOffset(); } } else { file[0] = null; } } }); if (file[0] != null && file[0].isValid()) { return new OpenFileDescriptor(refElement.getRefManager().getProject(), file[0], offset[0]); } return null; } private void syncBrowser() { if (myTree.getSelectionModel().getSelectionCount() != 1) { myBrowser.showEmpty(); } else { TreePath pathSelected = myTree.getSelectionModel().getLeadSelectionPath(); if (pathSelected != null) { final InspectionTreeNode node = (InspectionTreeNode)pathSelected.getLastPathComponent(); if (node instanceof RefElementNode) { final RefElementNode refElementNode = (RefElementNode)node; final CommonProblemDescriptor problem = refElementNode.getProblem(); final RefEntity refSelected = refElementNode.getElement(); if (problem != null) { showInBrowser(refSelected, problem); } else { showInBrowser(refSelected); } } else if (node instanceof ProblemDescriptionNode) { final ProblemDescriptionNode problemNode = (ProblemDescriptionNode)node; showInBrowser(problemNode.getElement(), problemNode.getDescriptor()); } else if (node instanceof InspectionNode) { showInBrowser(((InspectionNode)node).getToolWrapper()); } else { myBrowser.showEmpty(); } } } } private void showInBrowser(final RefEntity refEntity) { Cursor currentCursor = getCursor(); setCursor(new Cursor(Cursor.WAIT_CURSOR)); myBrowser.showPageFor(refEntity); setCursor(currentCursor); } private void showInBrowser(@NotNull InspectionToolWrapper toolWrapper) { Cursor currentCursor = getCursor(); setCursor(new Cursor(Cursor.WAIT_CURSOR)); myBrowser.showDescription(toolWrapper); setCursor(currentCursor); } private void showInBrowser(final RefEntity refEntity, CommonProblemDescriptor descriptor) { Cursor currentCursor = getCursor(); setCursor(new Cursor(Cursor.WAIT_CURSOR)); myBrowser.showPageFor(refEntity, descriptor); setCursor(currentCursor); } @NotNull public InspectionNode addTool(@NotNull final InspectionToolWrapper toolWrapper, HighlightDisplayLevel errorLevel, boolean groupedBySeverity) { String groupName = toolWrapper.getGroupDisplayName().isEmpty() ? InspectionProfileEntry.GENERAL_GROUP_NAME : toolWrapper.getGroupDisplayName(); InspectionTreeNode parentNode = getToolParentNode(groupName, errorLevel, groupedBySeverity); InspectionNode toolNode = new InspectionNode(toolWrapper); boolean showStructure = myGlobalInspectionContext.getUIOptions().SHOW_STRUCTURE; myProvider.appendToolNodeContent(myGlobalInspectionContext, toolNode, parentNode, showStructure); InspectionToolPresentation presentation = myGlobalInspectionContext.getPresentation(toolWrapper); toolNode = presentation.createToolNode(myGlobalInspectionContext, toolNode, myProvider, parentNode, showStructure); ((DefaultInspectionToolPresentation)presentation).myToolNode = toolNode; registerActionShortcuts(presentation); return toolNode; } private void registerActionShortcuts(@NotNull InspectionToolPresentation presentation) { final QuickFixAction[] fixes = presentation.getQuickFixes(RefEntity.EMPTY_ELEMENTS_ARRAY); if (fixes != null) { for (QuickFixAction fix : fixes) { fix.registerCustomShortcutSet(fix.getShortcutSet(), this); } } } private void clearTree() { myTree.removeAllNodes(); mySeverityGroupNodes.clear(); } @Nullable public String getCurrentProfileName() { return myInspectionProfile == null ? null : myInspectionProfile.getDisplayName(); } public InspectionProfile getCurrentProfile() { return myInspectionProfile; } public boolean update(){ return updateView(true); } public boolean updateView(boolean strict) { if (!strict && !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS){ myTree.repaint(); return false; } clearTree(); boolean resultsFound = buildTree(); myTree.restoreExpansionAndSelection(); return resultsFound; } private boolean buildTree() { InspectionProfile profile = myInspectionProfile; boolean isGroupedBySeverity = myGlobalInspectionContext.getUIOptions().GROUP_BY_SEVERITY; myGroups = new HashMap<HighlightDisplayLevel, Map<String, InspectionGroupNode>>(); final Map<String, Tools> tools = myGlobalInspectionContext.getTools(); boolean resultsFound = false; for (Tools currentTools : tools.values()) { InspectionToolWrapper defaultToolWrapper = currentTools.getDefaultState().getTool(); final HighlightDisplayKey key = HighlightDisplayKey.find(defaultToolWrapper.getShortName()); for (ScopeToolState state : currentTools.getTools()) { InspectionToolWrapper toolWrapper = state.getTool(); if (myProvider.checkReportedProblems(myGlobalInspectionContext, toolWrapper)) { addTool(toolWrapper, ((InspectionProfileImpl)profile).getErrorLevel(key, state.getScope(myProject), myProject), isGroupedBySeverity); resultsFound = true; } } } return resultsFound; } @NotNull public InspectionTreeNode getToolParentNode(@NotNull String groupName, HighlightDisplayLevel errorLevel, boolean groupedBySeverity) { if (groupName.isEmpty()) { return getRelativeRootNode(groupedBySeverity, errorLevel); } if (myGroups == null) { myGroups = new HashMap<HighlightDisplayLevel, Map<String, InspectionGroupNode>>(); } Map<String, InspectionGroupNode> map = myGroups.get(errorLevel); if (map == null) { map = new HashMap<String, InspectionGroupNode>(); myGroups.put(errorLevel, map); } Map<String, InspectionGroupNode> searchMap = new HashMap<String, InspectionGroupNode>(map); if (!groupedBySeverity) { for (Map<String, InspectionGroupNode> groupMap : myGroups.values()) { searchMap.putAll(groupMap); } } InspectionGroupNode group = searchMap.get(groupName); if (group == null) { group = new InspectionGroupNode(groupName); map.put(groupName, group); getRelativeRootNode(groupedBySeverity, errorLevel).add(group); } return group; } @NotNull private InspectionTreeNode getRelativeRootNode(boolean isGroupedBySeverity, HighlightDisplayLevel level) { if (isGroupedBySeverity) { if (mySeverityGroupNodes.containsKey(level)) { return mySeverityGroupNodes.get(level); } final InspectionSeverityGroupNode severityGroupNode = new InspectionSeverityGroupNode(myProject, level); mySeverityGroupNodes.put(level, severityGroupNode); myTree.getRoot().add(severityGroupNode); return severityGroupNode; } return myTree.getRoot(); } private OccurenceNavigator getOccurenceNavigator() { return myOccurenceNavigator; } @Override public boolean hasNextOccurence() { return myOccurenceNavigator != null && myOccurenceNavigator.hasNextOccurence(); } @Override public boolean hasPreviousOccurence() { return myOccurenceNavigator != null && myOccurenceNavigator.hasPreviousOccurence(); } @Override public OccurenceInfo goNextOccurence() { return myOccurenceNavigator != null ? myOccurenceNavigator.goNextOccurence() : null; } @Override public OccurenceInfo goPreviousOccurence() { return myOccurenceNavigator != null ? myOccurenceNavigator.goPreviousOccurence() : null; } @Override public String getNextOccurenceActionName() { return myOccurenceNavigator != null ? myOccurenceNavigator.getNextOccurenceActionName() : ""; } @Override public String getPreviousOccurenceActionName() { return myOccurenceNavigator != null ? myOccurenceNavigator.getPreviousOccurenceActionName() : ""; } @NotNull public Project getProject() { return myProject; } @Override public Object getData(String dataId) { if (PlatformDataKeys.HELP_ID.is(dataId)) return HELP_ID; if (DATA_KEY.is(dataId)) return this; if (myTree == null) return null; TreePath[] paths = myTree.getSelectionPaths(); if (paths == null || paths.length == 0) return null; if (paths.length > 1) { if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { return collectPsiElements(); } return null; } TreePath path = paths[0]; InspectionTreeNode selectedNode = (InspectionTreeNode)path.getLastPathComponent(); if (selectedNode instanceof RefElementNode) { final RefElementNode refElementNode = (RefElementNode)selectedNode; RefEntity refElement = refElementNode.getElement(); if (refElement == null) return null; final RefEntity item = refElement.getRefManager().getRefinedElement(refElement); if (!item.isValid()) return null; PsiElement psiElement = item instanceof RefElement ? ((RefElement)item).getElement() : null; if (psiElement == null) return null; final CommonProblemDescriptor problem = refElementNode.getProblem(); if (problem != null) { if (problem instanceof ProblemDescriptor) { psiElement = ((ProblemDescriptor)problem).getPsiElement(); if (psiElement == null) return null; } else { return null; } } if (CommonDataKeys.NAVIGATABLE.is(dataId)) { return getSelectedNavigatable(problem, psiElement); } else if (CommonDataKeys.PSI_ELEMENT.is(dataId)) { return psiElement.isValid() ? psiElement : null; } } else if (selectedNode instanceof ProblemDescriptionNode && CommonDataKeys.NAVIGATABLE.is(dataId)) { return getSelectedNavigatable(((ProblemDescriptionNode)selectedNode).getDescriptor()); } return null; } @Nullable private Navigatable getSelectedNavigatable(final CommonProblemDescriptor descriptor) { return getSelectedNavigatable(descriptor, descriptor instanceof ProblemDescriptor ? ((ProblemDescriptor)descriptor).getPsiElement() : null); } @Nullable private Navigatable getSelectedNavigatable(final CommonProblemDescriptor descriptor, final PsiElement psiElement) { if (descriptor instanceof ProblemDescriptorBase) { Navigatable navigatable = ((ProblemDescriptorBase) descriptor).getNavigatable(); if (navigatable != null) { return navigatable; } } if (psiElement == null || !psiElement.isValid()) return null; PsiFile containingFile = psiElement.getContainingFile(); VirtualFile virtualFile = containingFile == null ? null : containingFile.getVirtualFile(); if (virtualFile != null) { int startOffset = psiElement.getTextOffset(); if (descriptor instanceof ProblemDescriptorBase) { final TextRange textRange = ((ProblemDescriptorBase)descriptor).getTextRangeForNavigation(); if (textRange != null) { if (virtualFile instanceof VirtualFileWindow) { virtualFile = ((VirtualFileWindow)virtualFile).getDelegate(); } startOffset = textRange.getStartOffset(); } } return new OpenFileDescriptor(myProject, virtualFile, startOffset); } return null; } private PsiElement[] collectPsiElements() { RefEntity[] refElements = myTree.getSelectedElements(); List<PsiElement> psiElements = new ArrayList<PsiElement>(); for (RefEntity refElement : refElements) { PsiElement psiElement = refElement instanceof RefElement ? ((RefElement)refElement).getElement() : null; if (psiElement != null && psiElement.isValid()) { psiElements.add(psiElement); } } return PsiUtilCore.toPsiElementArray(psiElements); } private void popupInvoked(Component component, int x, int y) { final TreePath path = myTree.getLeadSelectionPath(); if (path == null) return; final DefaultActionGroup actions = new DefaultActionGroup(); final ActionManager actionManager = ActionManager.getInstance(); actions.add(actionManager.getAction(IdeActions.ACTION_EDIT_SOURCE)); actions.add(actionManager.getAction(IdeActions.ACTION_FIND_USAGES)); actions.add(myIncludeAction); actions.add(myExcludeAction); actions.addSeparator(); final InspectionToolWrapper toolWrapper = myTree.getSelectedToolWrapper(); if (toolWrapper != null) { final QuickFixAction[] quickFixes = myProvider.getQuickFixes(toolWrapper, myTree); if (quickFixes != null) { for (QuickFixAction quickFixe : quickFixes) { actions.add(quickFixe); } } final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); if (key == null) return; //e.g. DummyEntryPointsTool //options actions.addSeparator(); actions.add(new EditSettingsAction()); final List<AnAction> options = new InspectionsOptionsToolbarAction(this).createActions(); for (AnAction action : options) { actions.add(action); } } actions.addSeparator(); actions.add(actionManager.getAction(IdeActions.GROUP_VERSION_CONTROLS)); final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.CODE_INSPECTION, actions); menu.getComponent().show(component, x, y); } @NotNull public InspectionTree getTree(){ return myTree; } @NotNull public GlobalInspectionContextImpl getGlobalInspectionContext() { return myGlobalInspectionContext; } @NotNull public InspectionRVContentProvider getProvider() { return myProvider; } public boolean isSingleToolInSelection() { return myTree != null && myTree.getSelectedToolWrapper() != null; } public boolean isRerun() { boolean rerun = myRerun; myRerun = false; return rerun; } private InspectionProfile guessProfileToSelect(final InspectionProjectProfileManager profileManager) { final Set<InspectionProfile> profiles = new HashSet<InspectionProfile>(); final RefEntity[] selectedElements = myTree.getSelectedElements(); for (RefEntity selectedElement : selectedElements) { if (selectedElement instanceof RefElement) { final RefElement refElement = (RefElement)selectedElement; final PsiElement element = refElement.getElement(); if (element != null) { profiles.add(profileManager.getInspectionProfile()); } } } if (profiles.isEmpty()) { return (InspectionProfile)profileManager.getProjectProfileImpl(); } return profiles.iterator().next(); } public boolean isProfileDefined() { return myInspectionProfile != null && myInspectionProfile.isEditable(); } public static void showPopup(AnActionEvent e, JBPopup popup) { final InputEvent event = e.getInputEvent(); if (event instanceof MouseEvent) { popup.showUnderneathOf(event.getComponent()); } else { popup.showInBestPositionFor(e.getDataContext()); } } public AnalysisScope getScope() { return myScope; } private class CloseAction extends AnAction implements DumbAware { private CloseAction() { super(CommonBundle.message("action.close"), null, AllIcons.Actions.Cancel); } @Override public void actionPerformed(AnActionEvent e) { myGlobalInspectionContext.close(true); } } private class EditSettingsAction extends AnAction { private EditSettingsAction() { super(InspectionsBundle.message("inspection.action.edit.settings"), InspectionsBundle.message("inspection.action.edit.settings"), AllIcons.General.Settings); } @Override public void actionPerformed(AnActionEvent e) { final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(myProject); final InspectionToolWrapper toolWrapper = myTree.getSelectedToolWrapper(); InspectionProfile inspectionProfile = myInspectionProfile; final boolean profileIsDefined = isProfileDefined(); if (!profileIsDefined) { inspectionProfile = guessProfileToSelect(profileManager); } if (toolWrapper != null) { final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); //do not search for dead code entry point tool if (key != null){ if (new EditInspectionToolsSettingsAction(key).editToolSettings(myProject, (InspectionProfileImpl)inspectionProfile, profileIsDefined) && profileIsDefined){ updateCurrentProfile(); } return; } } if (EditInspectionToolsSettingsAction.editToolSettings(myProject, inspectionProfile, profileIsDefined, null) && profileIsDefined) { updateCurrentProfile(); } } } public void updateCurrentProfile() { final String name = myInspectionProfile.getName(); myInspectionProfile = (InspectionProfile)myInspectionProfile.getProfileManager().getProfile(name); } private class RerunAction extends AnAction { public RerunAction(JComponent comp) { super(InspectionsBundle.message("inspection.action.rerun"), InspectionsBundle.message("inspection.action.rerun"), AllIcons.Actions.Rerun); registerCustomShortcutSet(CommonShortcuts.getRerun(), comp); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(myScope.isValid()); } @Override public void actionPerformed(AnActionEvent e) { rerun(); } private void rerun() { myRerun = true; if (myScope.isValid()) { AnalysisUIOptions.getInstance(myProject).save(myGlobalInspectionContext.getUIOptions()); myGlobalInspectionContext.doInspections(myScope); } } } }