inspection tool window: count problems by highlighting level in tree (if different severities count < 6)

This commit is contained in:
Dmitry Batkovich
2016-04-15 14:45:40 +03:00
parent 375e08dd15
commit 49d868cdda
5 changed files with 183 additions and 81 deletions
@@ -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<TreeNode> children = TreeUtil.childrenToArray(node);
Collections.sort(children, InspectionResultsViewComparator.getInstance());
@@ -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<HighlightDisplayLevel, Integer> myItemCounter;
private final InspectionResultsView myView;
public InspectionTreeCellRenderer(InspectionResultsView view) {
myItemCounter = new FactoryMap<HighlightDisplayLevel, Integer>() {
@Nullable
@Override
protected Integer create(HighlightDisplayLevel key) {
return 0;
}
@Override
protected Map<HighlightDisplayLevel, Integer> createMap() {
return new TreeMap<>(new Comparator<Object>() {
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<HighlightDisplayLevel, Integer> 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();
}
}
@@ -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<HighlightDisplayLevel, Integer> counter) {
Enumeration enumeration = children();
while (enumeration.hasMoreElements()) {
InspectionTreeNode child = (InspectionTreeNode)enumeration.nextElement();
child.visitProblemSeverities(counter);
}
}
public int getProblemCount() {
int sum = 0;
Enumeration enumeration = children();
@@ -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<HighlightDisplayLevel, Integer> counter) {
counter.put(myLevel, counter.get(myLevel) + 1);
}
@Override
public boolean isValid() {
if (myElement instanceof RefElement && !myElement.isValid()) return false;
@@ -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<HighlightDisplayLevel, Integer> counter) {
if (isLeaf()) {
counter.put(HighlightDisplayLevel.WARNING, counter.get(HighlightDisplayLevel.WARNING) + 1);
return;
}
super.visitProblemSeverities(counter);
}
}