diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTree.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTree.java index 7fb971fd1e68..a675e19e80f8 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTree.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTree.java @@ -23,18 +23,11 @@ package com.intellij.codeInspection.ui; import com.intellij.codeInspection.CommonProblemDescriptor; -import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.ex.*; -import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.FileStatus; import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeComparator; -import com.intellij.ui.ColoredTreeCellRenderer; -import com.intellij.ui.JBColor; -import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.TreeSpeedSearch; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.containers.Convertor; @@ -44,7 +37,6 @@ import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.ExpandVetoException; @@ -59,12 +51,13 @@ public class InspectionTree extends Tree { private boolean myQueueUpdate; public InspectionTree(@NotNull Project project, - @NotNull GlobalInspectionContextImpl context, InspectionResultsView view) { + @NotNull GlobalInspectionContextImpl context, + @NotNull InspectionResultsView view) { setModel(new DefaultTreeModel(new InspectionRootNode(project, new InspectionTreeUpdater(view)))); myContext = context; myExcludedManager = view.getExcludedManager(); - setCellRenderer(new CellRenderer()); + setCellRenderer(new InspectionTreeCellRenderer(view)); setRootVisible(!myContext.isSingleInspectionRun()); setShowsRootHandles(true); UIUtil.setLineStyleAngled(this); @@ -320,75 +313,6 @@ public class InspectionTree extends Tree { } } - private class CellRenderer extends ColoredTreeCellRenderer { - /* private Project myProject; - InspectionManagerEx myManager; - public CellRenderer(Project project) { - myProject = project; - myManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); - }*/ - - @Override - public void customizeCellRenderer(JTree tree, - Object value, - boolean selected, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus) { - InspectionTreeNode node = (InspectionTreeNode)value; - - append(node.toString(), - patchAttr(node, appearsBold(node) ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : getMainForegroundAttributes(node))); - - int problemCount = node.getProblemCount(); - if (!leaf) { - append(" " + InspectionsBundle.message("inspection.problem.descriptor.count", problemCount), patchAttr(node, SimpleTextAttributes.GRAYED_ATTRIBUTES)); - } - - if (!node.isValid()) { - append(" " + InspectionsBundle.message("inspection.invalid.node.text"), patchAttr(node, SimpleTextAttributes.ERROR_ATTRIBUTES)); - } else { - setIcon(node.getIcon(expanded)); - } - // do not need reset model (for recalculation of prefered size) when digit number of problemCount is growth - // or INVALID marker appears - final String tail = StringUtil.repeat(" ", Math.max(0, 5- - String.valueOf(problemCount).length())); - append(tail); - } - - public SimpleTextAttributes patchAttr(InspectionTreeNode node, SimpleTextAttributes attributes) { - if (node.isResolved(myExcludedManager)) { - return new SimpleTextAttributes(attributes.getBgColor(), attributes.getFgColor(), attributes.getWaveColor(), attributes.getStyle() | SimpleTextAttributes.STYLE_STRIKEOUT); - } - return attributes; - } - - private SimpleTextAttributes getMainForegroundAttributes(InspectionTreeNode node) { - SimpleTextAttributes foreground = SimpleTextAttributes.REGULAR_ATTRIBUTES; - if (node instanceof RefElementNode) { - RefEntity refElement = ((RefElementNode)node).getElement(); - - if (refElement instanceof RefElement) { - refElement = ((RefElement)refElement).getContainingEntry(); - if (((RefElement)refElement).isEntry() && ((RefElement)refElement).isPermanentEntry()) { - foreground = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.blue); - } - } - - } - final FileStatus nodeStatus = node.getNodeStatus(); - if (nodeStatus != FileStatus.NOT_CHANGED){ - foreground = new SimpleTextAttributes(foreground.getBgColor(), nodeStatus.getColor(), foreground.getWaveColor(), foreground.getStyle()); - } - return foreground; - } - - private boolean appearsBold(Object node) { - return ((InspectionTreeNode)node).appearsBold(); - } - } - private void sortChildren(InspectionTreeNode node) { final List children = TreeUtil.childrenToArray(node); Collections.sort(children, InspectionResultsViewComparator.getInstance()); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeCellRenderer.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeCellRenderer.java new file mode 100644 index 000000000000..7b910e2eeb57 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeCellRenderer.java @@ -0,0 +1,143 @@ +/* + * Copyright 2000-2016 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.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; +import com.intellij.codeInspection.InspectionsBundle; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.JBColor; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.containers.FactoryMap; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.*; + +/** + * @author Dmitry Batkovich + */ +class InspectionTreeCellRenderer extends ColoredTreeCellRenderer { + private final static int MAX_LEVEL_TYPES = 5; + + private final FactoryMap myItemCounter; + private final InspectionResultsView myView; + + public InspectionTreeCellRenderer(InspectionResultsView view) { + myItemCounter = new FactoryMap() { + @Nullable + @Override + protected Integer create(HighlightDisplayLevel key) { + return 0; + } + + @Override + protected Map createMap() { + return new TreeMap<>(new Comparator() { + private final SeverityRegistrar myRegistrar = SeverityRegistrar.getSeverityRegistrar(view.getProject()); + + @Override + public int compare(Object o1, Object o2) { + return -myRegistrar.compare(((HighlightDisplayLevel) o1).getSeverity(), ((HighlightDisplayLevel) o2).getSeverity()); + } + }); + } + }; + myView = view; + } + + @Override + public void customizeCellRenderer(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + InspectionTreeNode node = (InspectionTreeNode)value; + + append(node.toString(), + patchAttr(node, appearsBold(node) ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : getMainForegroundAttributes(node))); + + if (!leaf) { + myItemCounter.clear(); + node.visitProblemSeverities(myItemCounter); + append(" "); + if (myItemCounter.size() > MAX_LEVEL_TYPES) { + append(InspectionsBundle.message("inspection.problem.descriptor.count", + myItemCounter.values().stream().reduce(0, (i, j) -> i + j)) + " ", + patchAttr(node, SimpleTextAttributes.GRAYED_ATTRIBUTES)); + } else { + for (Map.Entry entry : myItemCounter.entrySet()) { + final HighlightDisplayLevel level = entry.getKey(); + final Integer occur = entry.getValue(); + + SimpleTextAttributes attrs = SimpleTextAttributes.GRAY_ATTRIBUTES; + if (level == HighlightDisplayLevel.ERROR) { + attrs = attrs.derive(-1, JBColor.red.brighter(), null, null); + } + append(occur + " " + level.getName().toLowerCase(Locale.ENGLISH) + " ", patchAttr(node, attrs)); + } + } + } + + if (!node.isValid()) { + append(" " + InspectionsBundle.message("inspection.invalid.node.text"), patchAttr(node, SimpleTextAttributes.ERROR_ATTRIBUTES)); + } + else { + setIcon(node.getIcon(expanded)); + } + // do not need reset model (for recalculation of prefered size) when digit number of problemCount is growth + // or INVALID marker appears + append(StringUtil.repeat(" ", 50)); + } + + public SimpleTextAttributes patchAttr(InspectionTreeNode node, SimpleTextAttributes attributes) { + if (node.isResolved(myView.getExcludedManager())) { + return new SimpleTextAttributes(attributes.getBgColor(), attributes.getFgColor(), attributes.getWaveColor(), + attributes.getStyle() | SimpleTextAttributes.STYLE_STRIKEOUT); + } + return attributes; + } + + private static SimpleTextAttributes getMainForegroundAttributes(InspectionTreeNode node) { + SimpleTextAttributes foreground = SimpleTextAttributes.REGULAR_ATTRIBUTES; + if (node instanceof RefElementNode) { + RefEntity refElement = ((RefElementNode)node).getElement(); + + if (refElement instanceof RefElement) { + refElement = ((RefElement)refElement).getContainingEntry(); + if (((RefElement)refElement).isEntry() && ((RefElement)refElement).isPermanentEntry()) { + foreground = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.blue); + } + } + } + final FileStatus nodeStatus = node.getNodeStatus(); + if (nodeStatus != FileStatus.NOT_CHANGED) { + foreground = + new SimpleTextAttributes(foreground.getBgColor(), nodeStatus.getColor(), foreground.getWaveColor(), foreground.getStyle()); + } + return foreground; + } + + private static boolean appearsBold(Object node) { + return ((InspectionTreeNode)node).appearsBold(); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java index fbb0d61a4f23..94860eddedb5 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java @@ -16,13 +16,14 @@ package com.intellij.codeInspection.ui; +import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.openapi.vcs.FileStatus; +import com.intellij.util.containers.FactoryMap; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeNode; import java.util.Enumeration; @@ -39,6 +40,14 @@ public abstract class InspectionTreeNode extends DefaultMutableTreeNode { @Nullable public abstract Icon getIcon(boolean expanded); + public void visitProblemSeverities(FactoryMap counter) { + Enumeration enumeration = children(); + while (enumeration.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)enumeration.nextElement(); + child.visitProblemSeverities(counter); + } + } + public int getProblemCount() { int sum = 0; Enumeration enumeration = children(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java index b11124d742a4..0d5fb38c8a59 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java @@ -16,13 +16,17 @@ package com.intellij.codeInspection.ui; +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.*; +import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.icons.AllIcons; import com.intellij.openapi.vcs.FileStatus; import com.intellij.psi.PsiElement; +import com.intellij.util.containers.FactoryMap; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,6 +45,7 @@ public class ProblemDescriptionNode extends InspectionTreeNode implements RefEle protected final InspectionToolWrapper myToolWrapper; @NotNull protected final InspectionToolPresentation myPresentation; + private final HighlightDisplayLevel myLevel; public ProblemDescriptionNode(RefEntity element, CommonProblemDescriptor descriptor, @@ -51,7 +56,12 @@ public class ProblemDescriptionNode extends InspectionTreeNode implements RefEle myDescriptor = descriptor; myToolWrapper = toolWrapper; myPresentation = presentation; - } + final InspectionProfileImpl profile = (InspectionProfileImpl)presentation.getContext().getCurrentProfile(); + myLevel = descriptor instanceof ProblemDescriptor + ? profile.getErrorLevel(HighlightDisplayKey.find(toolWrapper.getShortName()), ((ProblemDescriptor)descriptor).getStartElement()) + : profile.getTools(toolWrapper.getID(), element.getRefManager().getProject()).getLevel(); + +} @NotNull public InspectionToolWrapper getToolWrapper() { @@ -83,6 +93,11 @@ public class ProblemDescriptionNode extends InspectionTreeNode implements RefEle return 1; } + @Override + public void visitProblemSeverities(FactoryMap counter) { + counter.put(myLevel, counter.get(myLevel) + 1); + } + @Override public boolean isValid() { if (myElement instanceof RefElement && !myElement.isValid()) return false; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java index be6e3f83e93b..8d9d027d19d2 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.ui; +import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.reference.RefDirectory; @@ -24,6 +25,7 @@ import com.intellij.codeInspection.reference.RefEntity; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.FileStatus; import com.intellij.ui.ComputableIcon; +import com.intellij.util.containers.FactoryMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -132,4 +134,13 @@ public class RefElementNode extends InspectionTreeNode implements RefElementAwar public int getProblemCount() { return Math.max(1, super.getProblemCount()); } + + @Override + public void visitProblemSeverities(FactoryMap counter) { + if (isLeaf()) { + counter.put(HighlightDisplayLevel.WARNING, counter.get(HighlightDisplayLevel.WARNING) + 1); + return; + } + super.visitProblemSeverities(counter); + } }