summaryrefslogtreecommitdiff
path: root/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java')
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java257
1 files changed, 257 insertions, 0 deletions
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
new file mode 100644
index 000000000000..966a456e1d38
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2000-2014 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.profile.codeInspection.ui.inspectionsTree;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInspection.ex.InspectionProfileImpl;
+import com.intellij.codeInspection.ex.ScopeToolState;
+import com.intellij.ide.IdeTooltip;
+import com.intellij.ide.IdeTooltipManager;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.profile.codeInspection.ui.InspectionsAggregationUtil;
+import com.intellij.profile.codeInspection.ui.table.ScopesAndSeveritiesTable;
+import com.intellij.profile.codeInspection.ui.table.ThreeStateCheckBoxRenderer;
+import com.intellij.ui.treeStructure.treetable.TreeTable;
+import com.intellij.ui.treeStructure.treetable.TreeTableModel;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.table.TableColumn;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class InspectionsConfigTreeTable extends TreeTable {
+ private final static Logger LOG = Logger.getInstance(InspectionsConfigTreeTable.class);
+
+ private final static int TREE_COLUMN = 0;
+ private final static int SEVERITIES_COLUMN = 1;
+ private final static int IS_ENABLED_COLUMN = 2;
+
+ public InspectionsConfigTreeTable(final InspectionsConfigTreeTableSettings settings) {
+ super(new InspectionsConfigTreeTableModel(settings));
+
+ final TableColumn severitiesColumn = getColumnModel().getColumn(SEVERITIES_COLUMN);
+ severitiesColumn.setMaxWidth(20);
+
+ final TableColumn isEnabledColumn = getColumnModel().getColumn(IS_ENABLED_COLUMN);
+ isEnabledColumn.setMaxWidth(20);
+ isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer());
+ isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer());
+
+ addMouseMotionListener(new MouseAdapter() {
+ @Override
+ public void mouseMoved(final MouseEvent e) {
+ final Point point = e.getPoint();
+ final int column = columnAtPoint(point);
+ if (column != SEVERITIES_COLUMN) {
+ return;
+ }
+ final int row = rowAtPoint(point);
+ final Object maybeIcon = getModel().getValueAt(row, column);
+ if (maybeIcon instanceof MultiScopeSeverityIcon) {
+ final LinkedHashMap<String, HighlightSeverity> scopeToAverageSeverityMap =
+ ((MultiScopeSeverityIcon)maybeIcon).getScopeToAverageSeverityMap();
+ IdeTooltipManager.getInstance().show(new IdeTooltip(InspectionsConfigTreeTable.this, point, new ScopesAndSeveritiesHintTable(scopeToAverageSeverityMap)), false);
+ }
+ }
+ });
+ }
+
+ public abstract static class InspectionsConfigTreeTableSettings {
+ private final TreeNode myRoot;
+ private final Project myProject;
+
+ public InspectionsConfigTreeTableSettings(final TreeNode root, final Project project) {
+ myRoot = root;
+ myProject = project;
+ }
+
+ public TreeNode getRoot() {
+ return myRoot;
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ protected abstract InspectionProfileImpl getInspectionProfile();
+
+ protected abstract void onChanged(InspectionConfigTreeNode node);
+ }
+
+ private static class InspectionsConfigTreeTableModel extends DefaultTreeModel implements TreeTableModel {
+
+ private final InspectionsConfigTreeTableSettings mySettings;
+
+ public InspectionsConfigTreeTableModel(final InspectionsConfigTreeTableSettings settings) {
+ super(settings.getRoot());
+ mySettings = settings;
+ }
+
+ @Override
+ public int getColumnCount() {
+ return 3;
+ }
+
+ @Nullable
+ @Override
+ public String getColumnName(final int column) {
+ return null;
+ }
+
+ @Override
+ public Class getColumnClass(final int column) {
+ switch (column) {
+ case TREE_COLUMN:
+ return TreeTableModel.class;
+ case SEVERITIES_COLUMN:
+ return Icon.class;
+ case IS_ENABLED_COLUMN:
+ return Boolean.class;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ @Nullable
+ @Override
+ public Object getValueAt(final Object node, final int column) {
+ if (column == TREE_COLUMN) {
+ return null;
+ }
+ final InspectionConfigTreeNode treeNode = (InspectionConfigTreeNode)node;
+ final List<HighlightDisplayKey> inspectionsKeys = InspectionsAggregationUtil.getInspectionsKeys(treeNode);
+ if (column == SEVERITIES_COLUMN) {
+ final MultiColoredHighlightSeverityIconSink sink = new MultiColoredHighlightSeverityIconSink();
+ for (final HighlightDisplayKey selectedInspectionsNode : inspectionsKeys) {
+ final String toolId = selectedInspectionsNode.toString();
+ if (mySettings.getInspectionProfile().getTools(toolId, mySettings.getProject()).isEnabled()) {
+ sink.put(mySettings.getInspectionProfile().getToolDefaultState(toolId, mySettings.getProject()),
+ mySettings.getInspectionProfile().getNonDefaultTools(toolId, mySettings.getProject()));
+ }
+ }
+ return sink.constructIcon();
+ } else if (column == IS_ENABLED_COLUMN) {
+ return isEnabled(inspectionsKeys);
+ }
+ throw new IllegalArgumentException();
+ }
+
+ @Nullable
+ private Boolean isEnabled(final List<HighlightDisplayKey> selectedInspectionsNodes) {
+ Boolean isPreviousEnabled = null;
+ for (final HighlightDisplayKey key : selectedInspectionsNodes) {
+ final boolean enabled = mySettings.getInspectionProfile().getTools(key.toString(), mySettings.getProject()).isEnabled();
+ if (isPreviousEnabled == null) {
+ isPreviousEnabled = enabled;
+ } else if (!isPreviousEnabled.equals(enabled)) {
+ return null;
+ }
+ }
+ return isPreviousEnabled;
+ }
+
+ @Override
+ public boolean isCellEditable(final Object node, final int column) {
+ return column == IS_ENABLED_COLUMN;
+ }
+
+ @Override
+ public void setValueAt(final Object aValue, final Object node, final int column) {
+ LOG.assertTrue(column == IS_ENABLED_COLUMN);
+ LOG.assertTrue(aValue != null);
+ final boolean doEnable = (Boolean) aValue;
+ for (final InspectionConfigTreeNode aNode : InspectionsAggregationUtil.getInspectionsNodes((InspectionConfigTreeNode) node)) {
+ final String toolId = aNode.getKey().toString();
+ if (doEnable) {
+ mySettings.getInspectionProfile().enableTool(toolId, mySettings.getProject());
+ } else {
+ mySettings.getInspectionProfile().disableTool(toolId, mySettings.getProject());
+ }
+ aNode.dropCache();
+ mySettings.onChanged(aNode);
+ }
+ }
+
+ @Override
+ public void setTree(final JTree tree) {
+ }
+ }
+
+ private static class MultiColoredHighlightSeverityIconSink {
+
+ private final LinkedHashMap<String, HighlightSeverity> myScopeToAverageSeverityMap = new LinkedHashMap<String, HighlightSeverity>();
+
+ private boolean myIsFirst = true;
+
+ public Icon constructIcon() {
+ if (myScopeToAverageSeverityMap.isEmpty()) {
+ return null;
+ }
+ //TODO order scopes
+ return !allScopesHasMixedSeverity()
+ ? new MultiScopeSeverityIcon(myScopeToAverageSeverityMap)
+ : ScopesAndSeveritiesTable.MIXED_FAKE_LEVEL.getIcon();
+ }
+
+ private boolean allScopesHasMixedSeverity() {
+ for (final Map.Entry<String, HighlightSeverity> e : myScopeToAverageSeverityMap.entrySet()) {
+ if (!ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY.equals(e.getValue())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void put(final ScopeToolState defaultState, final Collection<ScopeToolState> nonDefault) {
+ putOne(defaultState);
+ for (final ScopeToolState scopeToolState : nonDefault) {
+ putOne(scopeToolState);
+ }
+ if (myIsFirst) {
+ myIsFirst = false;
+ }
+ }
+
+ public 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());
+ } 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);
+ }
+ }
+ } else if (!ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY.equals(myScopeToAverageSeverityMap.get(scopeName))) {
+ myScopeToAverageSeverityMap.put(scopeName, ScopesAndSeveritiesTable.MIXED_FAKE_SEVERITY);
+ }
+ }
+ }
+}