From 3a5cc28e0181913a3f29fa64bf1c2ce95926eb18 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Fri, 19 Sep 2014 16:40:32 +0400 Subject: [PATCH] Inspections ui: 1. mixed severity for scope not shown if part of inspections which have no this scope have same severity for default scope 2. table tree updating fixed --- .../ui/SingleInspectionProfilePanel.java | 6 +- .../InspectionsConfigTreeTable.java | 136 ++++++++++++++---- .../ui/table/ScopesAndSeveritiesTable.java | 9 +- .../ui/table/SeverityRenderer.java | 19 ++- 4 files changed, 139 insertions(+), 31 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 2320d059c146..9a57aa20d7a4 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -754,6 +754,7 @@ public class SingleInspectionProfilePanel extends JPanel { final boolean toUpdate = mySelectedProfile.getErrorLevel(key, scope, project) != level; mySelectedProfile.setErrorLevel(key, level, null, project); if (toUpdate) node.dropCache(); + myTreeTable.updateUI(); } } @@ -817,7 +818,7 @@ public class SingleInspectionProfilePanel extends JPanel { @Override protected void onSettingsChanged() { - myTreeTable.getTree().updateUI(); + myTreeTable.updateUI(); } @Override @@ -827,12 +828,13 @@ public class SingleInspectionProfilePanel extends JPanel { @Override protected void onScopesOrderChanged() { - myTreeTable.getTree().updateUI(); + myTreeTable.updateUI(); updateOptionsAndDescriptionPanel(); } @Override protected void onScopeRemoved(final int scopesCount) { + myTreeTable.updateUI(); if (scopesCount == 1) { updateOptionsAndDescriptionPanel(); } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java index 75bb2b1ed0da..59c747eec329 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java @@ -33,8 +33,11 @@ import com.intellij.ui.DoubleClickListener; import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.ui.treeStructure.treetable.TreeTableModel; import com.intellij.ui.treeStructure.treetable.TreeTableTree; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.*; +import com.intellij.util.containers.HashSet; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -46,6 +49,7 @@ import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.*; import java.util.*; +import java.util.HashMap; import java.util.List; /** @@ -259,32 +263,122 @@ public class InspectionsConfigTreeTable extends TreeTable { } } + private static class SeverityAndOccurrences { + private HighlightSeverity myPrimarySeverity; + private final Map myOccurrences = new HashMap(); + + public void setSeverityToMixed() { + myPrimarySeverity = ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY; + } + + public SeverityAndOccurrences incOccurrences(final String toolName, final HighlightSeverity severity) { + if (myPrimarySeverity == null) { + myPrimarySeverity = severity; + } else if (!Comparing.equal(severity, myPrimarySeverity)) { + myPrimarySeverity = ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY; + } + myOccurrences.put(toolName, severity); + return this; + } + + public HighlightSeverity getPrimarySeverity() { + return myPrimarySeverity; + } + + public int getOccurrencesSize() { + return myOccurrences.size(); + } + + public Map getOccurrences() { + return myOccurrences; + } + } + private static class MultiColoredHighlightSeverityIconSink { - private final Map myScopeToAverageSeverityMap = new HashMap(); + + private final Map myScopeToAverageSeverityMap = new HashMap(); private String myDefaultScopeName; - private boolean myIsFirst = true; public Icon constructIcon(final InspectionProfileImpl inspectionProfile) { + final Map computedSeverities = computeSeverities(inspectionProfile); + + if (computedSeverities == null) { + return null; + } + + boolean allScopesHasMixedSeverity = true; + for (HighlightSeverity severity : computedSeverities.values()) { + if (!severity.equals(ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY)) { + allScopesHasMixedSeverity = false; + break; + } + } + return allScopesHasMixedSeverity + ? ScopesAndSeveritiesTable.MIXED_FAKE_LEVEL.getIcon() + : new MultiScopeSeverityIcon(computedSeverities, myDefaultScopeName, inspectionProfile); + } + + @Nullable + private Map computeSeverities(final InspectionProfileImpl inspectionProfile) { if (myScopeToAverageSeverityMap.isEmpty()) { return null; } - return !allScopesHasMixedSeverity() - ? new MultiScopeSeverityIcon(myScopeToAverageSeverityMap, myDefaultScopeName, inspectionProfile) - : ScopesAndSeveritiesTable.MIXED_FAKE_LEVEL.getIcon(); - } + final Map result = new HashMap(); + final Map.Entry entry = ContainerUtil.getFirstItem(myScopeToAverageSeverityMap.entrySet()); + result.put(entry.getKey(), entry.getValue().getPrimarySeverity()); + if (myScopeToAverageSeverityMap.size() == 1) { + return result; + } + String[] scopesOrder = inspectionProfile.getScopesOrder(); + if (scopesOrder == null || scopesOrder.length == 0) { + final ArrayList scopesList = new ArrayList(myScopeToAverageSeverityMap.keySet()); + scopesList.remove(myDefaultScopeName); + ContainerUtil.sort(scopesList); + scopesOrder = ArrayUtil.toStringArray(scopesList); + } - private boolean allScopesHasMixedSeverity() { - for (final Map.Entry e : myScopeToAverageSeverityMap.entrySet()) { - if (!ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY.equals(e.getValue())) { - return false; + final SeverityAndOccurrences defaultSeveritiesAndOccurrences = myScopeToAverageSeverityMap.get(myDefaultScopeName); + final int allInspectionsCount = defaultSeveritiesAndOccurrences.getOccurrencesSize(); + final Map allScopes = defaultSeveritiesAndOccurrences.getOccurrences(); + String[] reversedScopesOrder = ArrayUtil.reverseArray(scopesOrder); + for (String currentScope : reversedScopesOrder) { + final SeverityAndOccurrences currentSeverityAndOccurrences = myScopeToAverageSeverityMap.get(currentScope); + if (currentSeverityAndOccurrences == null) { + continue; + } + final HighlightSeverity currentSeverity = currentSeverityAndOccurrences.getPrimarySeverity(); + if (currentSeverity == ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY || + currentSeverityAndOccurrences.getOccurrencesSize() == allInspectionsCount) { + result.put(currentScope, currentSeverity); + } + else { + Set toolsToCheck = ContainerUtil.newHashSet(allScopes.keySet()); + toolsToCheck.removeAll(currentSeverityAndOccurrences.getOccurrences().keySet()); + boolean doContinue = false; + final Map lowerScopeOccurrences = myScopeToAverageSeverityMap.get(myDefaultScopeName).getOccurrences(); + for (String toolName : toolsToCheck) { + final HighlightSeverity currentToolSeverity = lowerScopeOccurrences.get(toolName); + if (currentToolSeverity != null) { + if (!currentSeverity.equals(currentToolSeverity)) { + result.put(currentScope, ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY); + doContinue = true; + break; + } + } + } + if (doContinue) { + continue; + } + result.put(currentScope, currentSeverity); } } - return true; + + return result; } - public void put(final ScopeToolState defaultState, final Collection nonDefault) { + public void put(@NotNull final ScopeToolState defaultState, @NotNull final List nonDefault) { putOne(defaultState); if (myDefaultScopeName == null) { myDefaultScopeName = defaultState.getScopeName(); @@ -292,25 +386,19 @@ public class InspectionsConfigTreeTable extends TreeTable { for (final ScopeToolState scopeToolState : nonDefault) { putOne(scopeToolState); } - if (myIsFirst) { - myIsFirst = false; - } } private void putOne(final ScopeToolState state) { final Icon icon = state.getLevel().getIcon(); final String scopeName = state.getScopeName(); if (icon instanceof HighlightDisplayLevel.SingleColorIconWithMask) { - if (myIsFirst) { - myScopeToAverageSeverityMap.put(scopeName, state.getLevel().getSeverity()); + final SeverityAndOccurrences severityAndOccurrences = myScopeToAverageSeverityMap.get(scopeName); + final String inspectionName = state.getTool().getShortName(); + if (severityAndOccurrences == null) { + myScopeToAverageSeverityMap.put(scopeName, new SeverityAndOccurrences().incOccurrences(inspectionName, state.getLevel().getSeverity())); } else { - final HighlightSeverity severity = myScopeToAverageSeverityMap.get(scopeName); - if (!ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY.equals(severity) && !Comparing.equal(severity, state.getLevel().getSeverity())) { - myScopeToAverageSeverityMap.put(scopeName, ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY); - } + severityAndOccurrences.incOccurrences(inspectionName, state.getLevel().getSeverity()); } - } else if (!ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY.equals(myScopeToAverageSeverityMap.get(scopeName))) { - myScopeToAverageSeverityMap.put(scopeName, ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY); } } } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java index 58e35083a247..766e501e00cf 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java @@ -78,8 +78,13 @@ public class ScopesAndSeveritiesTable extends JBTable { scopeEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer()); final TableColumn severityColumn = columnModel.getColumn(SEVERITY_COLUMN); - severityColumn.setCellRenderer(SeverityRenderer.create(tableSettings.getInspectionProfile())); - severityColumn.setCellEditor(SeverityRenderer.create(tableSettings.getInspectionProfile())); + severityColumn.setCellRenderer(SeverityRenderer.create(tableSettings.getInspectionProfile(), null)); + severityColumn.setCellEditor(SeverityRenderer.create(tableSettings.getInspectionProfile(), new Runnable() { + @Override + public void run() { + tableSettings.onSettingsChanged(); + } + })); setColumnSelectionAllowed(false); setRowSelectionAllowed(true); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java index e1b3d54b8fb7..39a0e83b71af 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java @@ -19,12 +19,14 @@ import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.ui.ComboBoxTableRenderer; +import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.profile.codeInspection.SeverityProvider; import com.intellij.profile.codeInspection.ui.LevelChooserAction; import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.MouseEvent; @@ -35,11 +37,14 @@ import java.util.SortedSet; * @author Dmitry Batkovich */ public class SeverityRenderer extends ComboBoxTableRenderer { - public SeverityRenderer(final SeverityState[] values) { + private final Runnable myOnClose; + + public SeverityRenderer(final SeverityState[] values, @Nullable final Runnable onClose) { super(values); + myOnClose = onClose; } - public static SeverityRenderer create(final InspectionProfileImpl inspectionProfile) { + public static SeverityRenderer create(final InspectionProfileImpl inspectionProfile, @Nullable final Runnable onClose) { final SortedSet severities = LevelChooserAction.getSeverities(((SeverityProvider)inspectionProfile.getProfileManager()).getOwnSeverityRegistrar()); return new SeverityRenderer(ContainerUtil.map2Array(severities, new SeverityState[severities.size()], new Function() { @@ -47,7 +52,7 @@ public class SeverityRenderer extends ComboBoxTableRenderer { public SeverityState fun(HighlightSeverity severity) { return new SeverityState(severity, true); } - })); + }), onClose); } @Override @@ -70,4 +75,12 @@ public class SeverityRenderer extends ComboBoxTableRenderer { public boolean isCellEditable(final EventObject event) { return !(event instanceof MouseEvent) || ((MouseEvent)event).getClickCount() >= 1; } + + @Override + public void onClosed(LightweightWindowEvent event) { + super.onClosed(event); + if (myOnClose != null) { + myOnClose.run(); + } + } }