| /* |
| * 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; |
| |
| import com.intellij.codeHighlighting.HighlightDisplayLevel; |
| import com.intellij.codeInsight.daemon.HighlightDisplayKey; |
| import com.intellij.codeInsight.daemon.impl.HighlightInfoType; |
| import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; |
| import com.intellij.codeInsight.daemon.impl.SeverityUtil; |
| import com.intellij.codeInsight.hint.HintUtil; |
| import com.intellij.codeInspection.InspectionProfile; |
| import com.intellij.codeInspection.InspectionsBundle; |
| import com.intellij.codeInspection.ModifiableModel; |
| import com.intellij.codeInspection.ex.*; |
| import com.intellij.icons.AllIcons; |
| import com.intellij.ide.CommonActionsManager; |
| import com.intellij.ide.DefaultTreeExpander; |
| import com.intellij.ide.TreeExpander; |
| import com.intellij.ide.ui.search.SearchUtil; |
| import com.intellij.ide.ui.search.SearchableOptionsRegistrar; |
| import com.intellij.lang.annotation.HighlightSeverity; |
| import com.intellij.openapi.actionSystem.*; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.editor.colors.TextAttributesKey; |
| import com.intellij.openapi.editor.markup.TextAttributes; |
| import com.intellij.openapi.options.ConfigurationException; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.Messages; |
| import com.intellij.openapi.ui.Splitter; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.JDOMUtil; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.profile.ApplicationProfileManager; |
| import com.intellij.profile.DefaultProjectProfileManager; |
| import com.intellij.profile.ProfileManager; |
| import com.intellij.profile.codeInspection.InspectionProfileManager; |
| import com.intellij.profile.codeInspection.InspectionProfileManagerImpl; |
| import com.intellij.profile.codeInspection.InspectionProjectProfileManager; |
| import com.intellij.profile.codeInspection.SeverityProvider; |
| import com.intellij.profile.codeInspection.ui.filter.InspectionFilterAction; |
| import com.intellij.profile.codeInspection.ui.filter.InspectionsFilter; |
| import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionConfigTreeNode; |
| import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeComparator; |
| import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeRenderer; |
| import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeTable; |
| import com.intellij.profile.codeInspection.ui.table.ScopesAndSeveritiesTable; |
| import com.intellij.psi.search.scope.packageSet.NamedScope; |
| import com.intellij.ui.*; |
| import com.intellij.ui.components.JBLabel; |
| import com.intellij.util.Alarm; |
| import com.intellij.util.Function; |
| import com.intellij.util.config.StorageAccessors; |
| import com.intellij.util.containers.*; |
| import com.intellij.util.ui.UIUtil; |
| import com.intellij.util.ui.tree.TreeUtil; |
| import com.intellij.xml.util.XmlStringUtil; |
| import gnu.trove.THashSet; |
| import org.jdom.Element; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.event.TreeExpansionEvent; |
| import javax.swing.event.TreeExpansionListener; |
| import javax.swing.event.TreeSelectionEvent; |
| import javax.swing.event.TreeSelectionListener; |
| import javax.swing.tree.DefaultTreeModel; |
| import javax.swing.tree.TreeNode; |
| import javax.swing.tree.TreePath; |
| import java.awt.*; |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.util.*; |
| import java.util.HashSet; |
| import java.util.List; |
| |
| /** |
| * User: anna |
| * Date: 31-May-2006 |
| */ |
| public class SingleInspectionProfilePanel extends JPanel { |
| private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionToolsPanel"); |
| @NonNls private static final String INSPECTION_FILTER_HISTORY = "INSPECTION_FILTER_HISTORY"; |
| private static final String UNDER_CONSTRUCTION = InspectionsBundle.message("inspection.tool.description.under.construction.text"); |
| private final List<ToolDescriptors> myInitialToolDescriptors = new ArrayList<ToolDescriptors>(); |
| private InspectionProfileImpl mySelectedProfile; |
| private JEditorPane myBrowser; |
| private JPanel myOptionsPanel; |
| private JPanel myInspectionProfilePanel = null; |
| private FilterComponent myProfileFilter; |
| private final InspectionsFilter myInspectionsFilter = new InspectionsFilter() { |
| @Override |
| protected void filterChanged() { |
| filterTree(myProfileFilter.getFilter()); |
| } |
| }; |
| private final InspectionConfigTreeNode myRoot = |
| new InspectionConfigTreeNode(InspectionsBundle.message("inspection.root.node.title")); |
| private final Alarm myAlarm = new Alarm(); |
| private boolean myModified = false; |
| private InspectionsConfigTreeTable myTreeTable; |
| private TreeExpander myTreeExpander; |
| @NotNull |
| private String myInitialProfile; |
| @NonNls private static final String EMPTY_HTML = "<html><body></body></html>"; |
| private boolean myIsInRestore = false; |
| @NonNls private static final String VERTICAL_DIVIDER_PROPORTION = "VERTICAL_DIVIDER_PROPORTION"; |
| @NonNls private static final String HORIZONTAL_DIVIDER_PROPORTION = "HORIZONTAL_DIVIDER_PROPORTION"; |
| private final StorageAccessors myProperties = StorageAccessors.createGlobal("SingleInspectionProfilePanel"); |
| |
| private boolean myShareProfile; |
| private final InspectionProjectProfileManager myProjectProfileManager; |
| private Splitter myRightSplitter; |
| private Splitter myMainSplitter; |
| |
| private String[] myInitialScopesOrder; |
| |
| public SingleInspectionProfilePanel(@NotNull InspectionProjectProfileManager projectProfileManager, |
| @NotNull String inspectionProfileName, |
| @NotNull ModifiableModel profile) { |
| super(new BorderLayout()); |
| myProjectProfileManager = projectProfileManager; |
| mySelectedProfile = (InspectionProfileImpl)profile; |
| myInitialProfile = inspectionProfileName; |
| myShareProfile = profile.getProfileManager() == projectProfileManager; |
| } |
| |
| private static VisibleTreeState getExpandedNodes(InspectionProfileImpl profile) { |
| if (profile.getProfileManager() instanceof ApplicationProfileManager) { |
| return AppInspectionProfilesVisibleTreeState.getInstance().getVisibleTreeState(profile); |
| } |
| else { |
| DefaultProjectProfileManager projectProfileManager = (DefaultProjectProfileManager)profile.getProfileManager(); |
| return ProjectInspectionProfilesVisibleTreeState.getInstance(projectProfileManager.getProject()).getVisibleTreeState(profile); |
| } |
| } |
| |
| private void initUI() { |
| myInspectionProfilePanel = createInspectionProfileSettingsPanel(); |
| add(myInspectionProfilePanel, BorderLayout.CENTER); |
| UserActivityWatcher userActivityWatcher = new UserActivityWatcher(); |
| userActivityWatcher.addUserActivityListener(new UserActivityListener() { |
| @Override |
| public void stateChanged() { |
| //invoke after all other listeners |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| if (mySelectedProfile == null) return; //panel was disposed |
| updateProperSettingsForSelection(); |
| wereToolSettingsModified(); |
| } |
| }); |
| } |
| }); |
| userActivityWatcher.register(myOptionsPanel); |
| updateSelectedProfileState(); |
| reset(); |
| } |
| |
| private void updateSelectedProfileState() { |
| if (mySelectedProfile == null) return; |
| restoreTreeState(); |
| repaintTableData(); |
| updateSelection(); |
| } |
| |
| public void updateSelection() { |
| if (myTreeTable != null) { |
| final TreePath selectionPath = myTreeTable.getTree().getSelectionPath(); |
| if (selectionPath != null) { |
| TreeUtil.selectNode(myTreeTable.getTree(), (TreeNode) selectionPath.getLastPathComponent()); |
| final int rowForPath = myTreeTable.getTree().getRowForPath(selectionPath); |
| TableUtil.selectRows(myTreeTable, new int[]{rowForPath}); |
| scrollToCenter(); |
| } |
| } |
| } |
| |
| |
| private void wereToolSettingsModified() { |
| for (final ToolDescriptors toolDescriptor : myInitialToolDescriptors) { |
| Descriptor desc = toolDescriptor.getDefaultDescriptor(); |
| if (wereToolSettingsModified(desc)) return; |
| List<Descriptor> descriptors = toolDescriptor.getNonDefaultDescriptors(); |
| for (Descriptor descriptor : descriptors) { |
| if (wereToolSettingsModified(descriptor)) return; |
| } |
| } |
| myModified = false; |
| } |
| |
| private boolean wereToolSettingsModified(Descriptor descriptor) { |
| InspectionToolWrapper toolWrapper = descriptor.getToolWrapper(); |
| if (!mySelectedProfile.isToolEnabled(descriptor.getKey(), descriptor.getScope(), myProjectProfileManager.getProject())) { |
| return false; |
| } |
| Element oldConfig = descriptor.getConfig(); |
| if (oldConfig == null) return false; |
| Element newConfig = Descriptor.createConfigElement(toolWrapper); |
| if (!JDOMUtil.areElementsEqual(oldConfig, newConfig)) { |
| myAlarm.cancelAllRequests(); |
| myAlarm.addRequest(new Runnable() { |
| @Override |
| public void run() { |
| myTreeTable.repaint(); |
| } |
| }, 300); |
| myModified = true; |
| return true; |
| } |
| return false; |
| } |
| |
| private void updateProperSettingsForSelection() { |
| final TreePath selectionPath = myTreeTable.getTree().getSelectionPath(); |
| if (selectionPath != null) { |
| InspectionConfigTreeNode node = (InspectionConfigTreeNode)selectionPath.getLastPathComponent(); |
| final Descriptor descriptor = node.getDefaultDescriptor(); |
| if (descriptor != null) { |
| final boolean properSetting = mySelectedProfile.isProperSetting(descriptor.getKey().toString()); |
| if (node.isProperSetting() != properSetting) { |
| myAlarm.cancelAllRequests(); |
| myAlarm.addRequest(new Runnable() { |
| @Override |
| public void run() { |
| myTreeTable.repaint(); |
| } |
| }, 300); |
| node.dropCache(); |
| updateUpHierarchy(node, (InspectionConfigTreeNode)node.getParent()); |
| } |
| } |
| } |
| } |
| |
| private void initToolStates() { |
| final InspectionProfileImpl profile = mySelectedProfile; |
| if (profile == null) return; |
| myInitialToolDescriptors.clear(); |
| final Project project = myProjectProfileManager.getProject(); |
| for (final ScopeToolState state : profile.getDefaultStates(myProjectProfileManager.getProject())) { |
| if (!accept(state.getTool())) continue; |
| myInitialToolDescriptors.add(ToolDescriptors.fromScopeToolState(state, profile, project)); |
| } |
| myInitialScopesOrder = mySelectedProfile.getScopesOrder(); |
| } |
| |
| protected boolean accept(InspectionToolWrapper entry) { |
| return entry.getDefaultLevel() != HighlightDisplayLevel.NON_SWITCHABLE_ERROR; |
| } |
| |
| private void postProcessModification() { |
| wereToolSettingsModified(); |
| //resetup configs |
| for (ScopeToolState state : mySelectedProfile.getAllTools(myProjectProfileManager.getProject())) { |
| state.resetConfigPanel(); |
| } |
| fillTreeData(myProfileFilter.getFilter(), true); |
| repaintTableData(); |
| updateOptionsAndDescriptionPanel(myTreeTable.getTree().getSelectionPaths()); |
| } |
| |
| @Nullable |
| public static ModifiableModel createNewProfile(final int initValue, |
| ModifiableModel selectedProfile, |
| JPanel parent, |
| String profileName, |
| Set<String> existingProfileNames, |
| @NotNull Project project) { |
| profileName = Messages.showInputDialog(parent, profileName, "Create New Inspection Profile", Messages.getQuestionIcon()); |
| if (profileName == null) return null; |
| final ProfileManager profileManager = selectedProfile.getProfileManager(); |
| if (existingProfileNames.contains(profileName)) { |
| Messages.showErrorDialog(InspectionsBundle.message("inspection.unable.to.create.profile.message", profileName), |
| InspectionsBundle.message("inspection.unable.to.create.profile.dialog.title")); |
| return null; |
| } |
| InspectionProfileImpl inspectionProfile = |
| new InspectionProfileImpl(profileName, InspectionToolRegistrar.getInstance(), profileManager); |
| if (initValue == -1) { |
| inspectionProfile.initInspectionTools(project); |
| ModifiableModel profileModifiableModel = inspectionProfile.getModifiableModel(); |
| final InspectionToolWrapper[] profileEntries = profileModifiableModel.getInspectionTools(null); |
| for (InspectionToolWrapper toolWrapper : profileEntries) { |
| profileModifiableModel.disableTool(toolWrapper.getShortName(), null, project); |
| } |
| profileModifiableModel.setLocal(true); |
| profileModifiableModel.setModified(true); |
| return profileModifiableModel; |
| } else if (initValue == 0) { |
| inspectionProfile.copyFrom(selectedProfile); |
| inspectionProfile.setName(profileName); |
| inspectionProfile.initInspectionTools(project); |
| inspectionProfile.setModified(true); |
| return inspectionProfile; |
| } |
| return null; |
| } |
| |
| public void setFilter(String filter) { |
| myProfileFilter.setFilter(filter); |
| } |
| |
| private void filterTree(@Nullable String filter) { |
| if (myTreeTable != null) { |
| getExpandedNodes(mySelectedProfile).saveVisibleState(myTreeTable.getTree()); |
| fillTreeData(filter, true); |
| reloadModel(); |
| restoreTreeState(); |
| if (myTreeTable.getTree().getSelectionPath() == null) { |
| TreeUtil.selectFirstNode(myTreeTable.getTree()); |
| } |
| } |
| } |
| |
| private void filterTree() { |
| filterTree(myProfileFilter != null ? myProfileFilter.getFilter() : null); |
| } |
| |
| private void reloadModel() { |
| try { |
| myIsInRestore = true; |
| ((DefaultTreeModel)myTreeTable.getTree().getModel()).reload(); |
| } |
| finally { |
| myIsInRestore = false; |
| } |
| |
| } |
| |
| private void restoreTreeState() { |
| |
| try { |
| myIsInRestore = true; |
| getExpandedNodes(mySelectedProfile).restoreVisibleState(myTreeTable.getTree()); |
| } |
| finally { |
| myIsInRestore = false; |
| } |
| } |
| |
| private ActionToolbar createTreeToolbarPanel() { |
| final CommonActionsManager actionManager = CommonActionsManager.getInstance(); |
| |
| DefaultActionGroup actions = new DefaultActionGroup(); |
| |
| actions.add(new InspectionFilterAction(mySelectedProfile, myInspectionsFilter)); |
| actions.addSeparator(); |
| |
| actions.add(actionManager.createExpandAllAction(myTreeExpander, myTreeTable)); |
| actions.add(actionManager.createCollapseAllAction(myTreeExpander, myTreeTable)); |
| actions.add(new AnAction("Reset to Empty", "Reset to empty", AllIcons.Actions.Reset_to_empty){ |
| |
| @Override |
| public void update(AnActionEvent e) { |
| e.getPresentation().setEnabled(mySelectedProfile != null && mySelectedProfile.isExecutable(myProjectProfileManager.getProject())); |
| } |
| |
| @Override |
| public void actionPerformed(AnActionEvent e) { |
| mySelectedProfile.resetToEmpty(e.getProject()); |
| postProcessModification(); |
| } |
| }); |
| |
| actions.add(new AdvancedSettingsAction(myProjectProfileManager.getProject(), myRoot) { |
| @Override |
| protected InspectionProfileImpl getInspectionProfile() { |
| return mySelectedProfile; |
| } |
| |
| @Override |
| protected void postProcessModification() { |
| SingleInspectionProfilePanel.this.postProcessModification(); |
| } |
| }); |
| |
| |
| final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true); |
| actionToolbar.setTargetComponent(this); |
| return actionToolbar; |
| } |
| |
| private void repaintTableData() { |
| if (myTreeTable != null) { |
| getExpandedNodes(mySelectedProfile).saveVisibleState(myTreeTable.getTree()); |
| reloadModel(); |
| restoreTreeState(); |
| } |
| } |
| |
| public void selectInspectionTool(String name) { |
| final InspectionConfigTreeNode node = findNodeByKey(name, myRoot); |
| if (node != null) { |
| TreeUtil.selectNode(myTreeTable.getTree(), node); |
| final int rowForPath = myTreeTable.getTree().getRowForPath(new TreePath(node.getPath())); |
| TableUtil.selectRows(myTreeTable, new int[]{rowForPath}); |
| scrollToCenter(); |
| } |
| } |
| |
| private void scrollToCenter() { |
| ListSelectionModel selectionModel = myTreeTable.getSelectionModel(); |
| int maxSelectionIndex = selectionModel.getMaxSelectionIndex(); |
| final int maxColumnSelectionIndex = Math.max(0, myTreeTable.getColumnModel().getSelectionModel().getMinSelectionIndex()); |
| Rectangle maxCellRect = myTreeTable.getCellRect(maxSelectionIndex, maxColumnSelectionIndex, false); |
| |
| final Point selectPoint = maxCellRect.getLocation(); |
| final int allHeight = myTreeTable.getVisibleRect().height; |
| myTreeTable.scrollRectToVisible(new Rectangle(new Point(0, Math.max(0, selectPoint.y - allHeight / 2)), new Dimension(0, allHeight))); |
| } |
| |
| @Nullable |
| private static InspectionConfigTreeNode findNodeByKey(String name, InspectionConfigTreeNode root) { |
| for (int i = 0; i < root.getChildCount(); i++) { |
| final InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i); |
| final Descriptor descriptor = child.getDefaultDescriptor(); |
| if (descriptor != null) { |
| if (descriptor.getKey().toString().equals(name)) { |
| return child; |
| } |
| } |
| else { |
| final InspectionConfigTreeNode node = findNodeByKey(name, child); |
| if (node != null) return node; |
| } |
| } |
| return null; |
| } |
| |
| private JScrollPane initTreeScrollPane() { |
| fillTreeData(null, true); |
| |
| final InspectionsConfigTreeRenderer renderer = new InspectionsConfigTreeRenderer(){ |
| @Override |
| protected String getFilter() { |
| return myProfileFilter != null ? myProfileFilter.getFilter() : null; |
| } |
| }; |
| myTreeTable = new InspectionsConfigTreeTable(new InspectionsConfigTreeTable.InspectionsConfigTreeTableSettings(myRoot, myProjectProfileManager.getProject()) { |
| @Override |
| protected void onChanged(final InspectionConfigTreeNode node) { |
| updateOptionsAndDescriptionPanel(); |
| updateUpHierarchy(node, (InspectionConfigTreeNode)node.getParent()); |
| } |
| |
| @Override |
| public InspectionProfileImpl getInspectionProfile() { |
| return mySelectedProfile; |
| } |
| }); |
| myTreeTable.setTreeCellRenderer(renderer); |
| myTreeTable.setRootVisible(false); |
| UIUtil.setLineStyleAngled(myTreeTable.getTree()); |
| TreeUtil.installActions(myTreeTable.getTree()); |
| |
| |
| myTreeTable.getTree().addTreeSelectionListener(new TreeSelectionListener() { |
| @Override |
| public void valueChanged(TreeSelectionEvent e) { |
| if (myTreeTable.getTree().getSelectionPaths() != null) { |
| updateOptionsAndDescriptionPanel(myTreeTable.getTree().getSelectionPaths()); |
| } |
| else { |
| initOptionsAndDescriptionPanel(); |
| } |
| |
| if (!myIsInRestore) { |
| InspectionProfileImpl selected = mySelectedProfile; |
| if (selected != null) { |
| InspectionProfileImpl baseProfile = (InspectionProfileImpl)selected.getParentProfile(); |
| if (baseProfile != null) { |
| getExpandedNodes(baseProfile).setSelectionPaths(myTreeTable.getTree().getSelectionPaths()); |
| } |
| getExpandedNodes(selected).setSelectionPaths(myTreeTable.getTree().getSelectionPaths()); |
| } |
| } |
| |
| } |
| }); |
| |
| |
| myTreeTable.addMouseListener(new PopupHandler() { |
| @Override |
| public void invokePopup(Component comp, int x, int y) { |
| final int[] selectionRows = myTreeTable.getTree().getSelectionRows(); |
| if (selectionRows != null && |
| myTreeTable.getTree().getPathForLocation(x, y) != null && |
| Arrays.binarySearch(selectionRows, myTreeTable.getTree().getRowForLocation(x, y)) > -1) { |
| compoundPopup().show(comp, x, y); |
| } |
| } |
| }); |
| |
| |
| new TreeSpeedSearch(myTreeTable.getTree(), new Convertor<TreePath, String>() { |
| @Override |
| public String convert(TreePath o) { |
| final InspectionConfigTreeNode node = (InspectionConfigTreeNode)o.getLastPathComponent(); |
| final Descriptor descriptor = node.getDefaultDescriptor(); |
| return descriptor != null ? InspectionsConfigTreeComparator.getDisplayTextToSort(descriptor.getText()) : InspectionsConfigTreeComparator |
| .getDisplayTextToSort(node.getGroupName()); |
| } |
| }); |
| |
| |
| final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable); |
| myTreeTable.getTree().setShowsRootHandles(true); |
| scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); |
| TreeUtil.collapseAll(myTreeTable.getTree(), 1); |
| |
| myTreeTable.getTree().addTreeExpansionListener(new TreeExpansionListener() { |
| |
| |
| @Override |
| public void treeCollapsed(TreeExpansionEvent event) { |
| InspectionProfileImpl selected = mySelectedProfile; |
| final InspectionConfigTreeNode node = (InspectionConfigTreeNode)event.getPath().getLastPathComponent(); |
| final InspectionProfileImpl parentProfile = (InspectionProfileImpl)selected.getParentProfile(); |
| if (parentProfile != null) { |
| getExpandedNodes(parentProfile).saveVisibleState(myTreeTable.getTree()); |
| } |
| getExpandedNodes(selected).saveVisibleState(myTreeTable.getTree()); |
| } |
| |
| @Override |
| public void treeExpanded(TreeExpansionEvent event) { |
| InspectionProfileImpl selected = mySelectedProfile; |
| if (selected != null) { |
| final InspectionConfigTreeNode node = (InspectionConfigTreeNode)event.getPath().getLastPathComponent(); |
| final InspectionProfileImpl parentProfile = (InspectionProfileImpl)selected.getParentProfile(); |
| if (parentProfile != null) { |
| getExpandedNodes(parentProfile).expandNode(node); |
| } |
| getExpandedNodes(selected).expandNode(node); |
| } |
| } |
| }); |
| |
| myTreeExpander = new DefaultTreeExpander(myTreeTable.getTree()) { |
| @Override |
| public boolean canExpand() { |
| return myTreeTable.isShowing(); |
| } |
| |
| @Override |
| public boolean canCollapse() { |
| return myTreeTable.isShowing(); |
| } |
| }; |
| myProfileFilter = new MyFilterComponent(); |
| |
| return scrollPane; |
| } |
| |
| private JPopupMenu compoundPopup() { |
| final DefaultActionGroup group = new DefaultActionGroup(); |
| final SeverityRegistrar severityRegistrar = ((SeverityProvider)mySelectedProfile.getProfileManager()).getOwnSeverityRegistrar(); |
| TreeSet<HighlightSeverity> severities = new TreeSet<HighlightSeverity>(severityRegistrar); |
| severities.add(HighlightSeverity.ERROR); |
| severities.add(HighlightSeverity.WARNING); |
| severities.add(HighlightSeverity.WEAK_WARNING); |
| final Collection<SeverityRegistrar.SeverityBasedTextAttributes> infoTypes = |
| SeverityUtil.getRegisteredHighlightingInfoTypes(severityRegistrar); |
| for (SeverityRegistrar.SeverityBasedTextAttributes info : infoTypes) { |
| severities.add(info.getSeverity()); |
| } |
| for (HighlightSeverity severity : severities) { |
| final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity); |
| group.add(new AnAction(renderSeverity(severity), renderSeverity(severity), level.getIcon()) { |
| @Override |
| public void actionPerformed(AnActionEvent e) { |
| setNewHighlightingLevel(level); |
| } |
| }); |
| } |
| group.add(Separator.getInstance()); |
| ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); |
| return menu.getComponent(); |
| } |
| |
| public static String renderSeverity(HighlightSeverity severity) { |
| return StringUtil.capitalizeWords(severity.getName().toLowerCase(), true); |
| } |
| |
| private static void updateUpHierarchy(final InspectionConfigTreeNode node, final InspectionConfigTreeNode parent) { |
| if (parent != null) { |
| parent.dropCache(); |
| updateUpHierarchy(parent, (InspectionConfigTreeNode)parent.getParent()); |
| } |
| } |
| |
| private static boolean isDescriptorAccepted(Descriptor descriptor, |
| @NonNls String filter, |
| final boolean forceInclude, |
| final List<Set<String>> keySetList, final Set<String> quoted) { |
| filter = filter.toLowerCase(); |
| if (StringUtil.containsIgnoreCase(descriptor.getText(), filter)) { |
| return true; |
| } |
| final String[] groupPath = descriptor.getGroup(); |
| for (String group : groupPath) { |
| if (StringUtil.containsIgnoreCase(group, filter)) { |
| return true; |
| } |
| } |
| for (String stripped : quoted) { |
| if (StringUtil.containsIgnoreCase(descriptor.getText(),stripped)) { |
| return true; |
| } |
| for (String group : groupPath) { |
| if (StringUtil.containsIgnoreCase(group,stripped)) { |
| return true; |
| } |
| } |
| final String description = descriptor.getToolWrapper().loadDescription(); |
| if (description != null && StringUtil.containsIgnoreCase(description.toLowerCase(), stripped)) { |
| if (!forceInclude) return true; |
| } else if (forceInclude) return false; |
| } |
| for (Set<String> keySet : keySetList) { |
| if (keySet.contains(descriptor.getKey().toString())) { |
| if (!forceInclude) { |
| return true; |
| } |
| } |
| else { |
| if (forceInclude) { |
| return false; |
| } |
| } |
| } |
| return forceInclude; |
| } |
| |
| private void fillTreeData(@Nullable String filter, boolean forceInclude) { |
| if (mySelectedProfile == null) return; |
| myRoot.removeAllChildren(); |
| myRoot.dropCache(); |
| List<Set<String>> keySetList = new ArrayList<Set<String>>(); |
| final Set<String> quoted = new HashSet<String>(); |
| if (filter != null && !filter.isEmpty()) { |
| keySetList.addAll(SearchUtil.findKeys(filter, quoted)); |
| } |
| Project project = myProjectProfileManager.getProject(); |
| final boolean emptyFilter = myInspectionsFilter.isEmptyFilter(); |
| for (ToolDescriptors toolDescriptors : myInitialToolDescriptors) { |
| final Descriptor descriptor = toolDescriptors.getDefaultDescriptor(); |
| if (filter != null && !filter.isEmpty() && !isDescriptorAccepted(descriptor, filter, forceInclude, keySetList, quoted)) { |
| continue; |
| } |
| if (!emptyFilter && !myInspectionsFilter.matches(mySelectedProfile.getTools(toolDescriptors.getDefaultDescriptor().getKey().toString(), project))) { |
| continue; |
| } |
| final InspectionConfigTreeNode node = new InspectionConfigTreeNode(toolDescriptors); |
| getGroupNode(myRoot, toolDescriptors.getDefaultDescriptor().getGroup()).add(node); |
| myRoot.dropCache(); |
| } |
| if (filter != null && forceInclude && myRoot.getChildCount() == 0) { |
| final Set<String> filters = SearchableOptionsRegistrar.getInstance().getProcessedWords(filter); |
| if (filters.size() > 1 || !quoted.isEmpty()) { |
| fillTreeData(filter, false); |
| } |
| } |
| TreeUtil.sort(myRoot, new InspectionsConfigTreeComparator()); |
| } |
| |
| private void updateOptionsAndDescriptionPanel(final TreePath... paths) { |
| if (mySelectedProfile == null || paths == null || paths.length == 0) { |
| return; |
| } |
| final TreePath path = paths[0]; |
| if (path == null) return; |
| final List<InspectionConfigTreeNode> nodes = InspectionsAggregationUtil.getInspectionsNodes(paths); |
| if (!nodes.isEmpty()) { |
| final InspectionConfigTreeNode singleNode = paths.length == 1 && ((InspectionConfigTreeNode)paths[0].getLastPathComponent()).getDefaultDescriptor() != null |
| ? ContainerUtil.getFirstItem(nodes) : null; |
| if (singleNode != null && singleNode.getDefaultDescriptor().loadDescription() != null) { |
| // need this in order to correctly load plugin-supplied descriptions |
| final Descriptor defaultDescriptor = singleNode.getDefaultDescriptor(); |
| final String description = defaultDescriptor.loadDescription(); |
| try { |
| final HintHint hintHint = new HintHint(myBrowser, new Point(0, 0)); |
| hintHint.setFont(myBrowser.getFont()); |
| myBrowser |
| .read(new StringReader(SearchUtil.markup(HintUtil.prepareHintText(description, hintHint), myProfileFilter.getFilter())), null); |
| } |
| catch (IOException e2) { |
| try { |
| //noinspection HardCodedStringLiteral |
| myBrowser.read(new StringReader(XmlStringUtil.wrapInHtml("<b>" + UNDER_CONSTRUCTION + "</b>")), null); |
| } |
| catch (IOException e1) { |
| //Can't be |
| } |
| } |
| catch (Throwable t) { |
| LOG.error("Failed to load description for: " + |
| defaultDescriptor.getToolWrapper().getTool().getClass() + |
| "; description: " + |
| description, t); |
| } |
| |
| } |
| else { |
| try { |
| myBrowser.read(new StringReader("<html><body>Multiple inspections are selected. You can edit them as a single inspection.</body></html>"), null); |
| } |
| catch (IOException e1) { |
| //Can't be |
| } |
| } |
| |
| myOptionsPanel.removeAll(); |
| final Project project = myProjectProfileManager.getProject(); |
| final JPanel severityPanel = new JPanel(new GridBagLayout()); |
| final double severityPanelWeightY; |
| final JPanel configPanelAnchor = new JPanel(new GridLayout()); |
| |
| final Set<String> scopesNames = new THashSet<String>(); |
| for (final InspectionConfigTreeNode node : nodes) { |
| final List<ScopeToolState> nonDefaultTools = mySelectedProfile.getNonDefaultTools(node.getDefaultDescriptor().getKey().toString(), project); |
| for (final ScopeToolState tool : nonDefaultTools) { |
| scopesNames.add(tool.getScopeName()); |
| } |
| } |
| |
| if (scopesNames.isEmpty()) { |
| |
| final LevelChooserAction severityLevelChooser = |
| new LevelChooserAction(mySelectedProfile) { |
| @Override |
| protected void onChosen(final HighlightSeverity severity) { |
| final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity); |
| for (final InspectionConfigTreeNode node : nodes) { |
| final HighlightDisplayKey key = node.getDefaultDescriptor().getKey(); |
| final NamedScope scope = node.getDefaultDescriptor().getScope(); |
| final boolean toUpdate = mySelectedProfile.getErrorLevel(key, scope, project) != level; |
| mySelectedProfile.setErrorLevel(key, level, null, project); |
| if (toUpdate) node.dropCache(); |
| } |
| |
| } |
| }; |
| final HighlightSeverity severity = |
| ScopesAndSeveritiesTable.getSeverity(ContainerUtil.map(nodes, new Function<InspectionConfigTreeNode, ScopeToolState>() { |
| @Override |
| public ScopeToolState fun(InspectionConfigTreeNode node) { |
| return node.getDefaultDescriptor().getState(); |
| } |
| })); |
| severityLevelChooser.setChosen(severity); |
| |
| final ScopesChooser scopesChooser = new ScopesChooser(ContainerUtil.map(nodes, new Function<InspectionConfigTreeNode, Descriptor>() { |
| @Override |
| public Descriptor fun(final InspectionConfigTreeNode node) { |
| return node.getDefaultDescriptor(); |
| } |
| }), mySelectedProfile, project, null) { |
| @Override |
| protected void onScopesOrderChanged() { |
| myTreeTable.getTree().updateUI(); |
| updateOptionsAndDescriptionPanel(); |
| } |
| |
| @Override |
| protected void onScopeAdded() { |
| updateOptionsAndDescriptionPanel(); |
| } |
| }; |
| |
| severityPanel.add(new JLabel(InspectionsBundle.message("inspection.severity")), |
| new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, |
| new Insets(10, 0, 10, 10), 0, 0)); |
| severityPanel.add(severityLevelChooser.createCustomComponent(severityLevelChooser.getTemplatePresentation()), |
| new GridBagConstraints(1, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, |
| new Insets(10, 0, 10, 0), 0, 0)); |
| severityPanel.add(scopesChooser.createCustomComponent(scopesChooser.getTemplatePresentation()), |
| new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, |
| new Insets(10, 0, 10, 0), 0, 0)); |
| severityPanelWeightY = 0.0; |
| if (singleNode != null) { |
| setConfigPanel(configPanelAnchor, mySelectedProfile.getToolDefaultState(singleNode.getDefaultDescriptor().getKey().toString(), |
| project)); |
| } |
| } |
| else { |
| if (singleNode != null) { |
| for (final Descriptor descriptor : singleNode.getDescriptors().getNonDefaultDescriptors()) { |
| descriptor.loadConfig(); |
| } |
| } |
| final JTable scopesAndScopesAndSeveritiesTable = |
| new ScopesAndSeveritiesTable(new ScopesAndSeveritiesTable.TableSettings(nodes, mySelectedProfile, project) { |
| @Override |
| protected void onScopeChosen(@NotNull final ScopeToolState state) { |
| setConfigPanel(configPanelAnchor, state); |
| configPanelAnchor.revalidate(); |
| configPanelAnchor.repaint(); |
| } |
| |
| @Override |
| protected void onSettingsChanged() { |
| myTreeTable.getTree().updateUI(); |
| } |
| |
| @Override |
| protected void onScopeAdded() { |
| updateOptionsAndDescriptionPanel(); |
| } |
| |
| @Override |
| protected void onScopesOrderChanged() { |
| myTreeTable.getTree().updateUI(); |
| updateOptionsAndDescriptionPanel(); |
| } |
| |
| @Override |
| protected void onScopeRemoved(final int scopesCount) { |
| if (scopesCount == 1) { |
| updateOptionsAndDescriptionPanel(); |
| } |
| } |
| }); |
| |
| |
| final ToolbarDecorator wrappedTable = ToolbarDecorator.createDecorator(scopesAndScopesAndSeveritiesTable).disableUpDownActions(); |
| final JPanel panel = wrappedTable.createPanel(); |
| panel.setMinimumSize(new Dimension(getMinimumSize().width, 3 * scopesAndScopesAndSeveritiesTable.getRowHeight())); |
| severityPanel.add(new JBLabel("Scopes & Severities"), |
| new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, |
| new Insets(5, 0, 2, 10), 0, 0)); |
| severityPanel.add(new JBLabel("Add scope to change its settings", UIUtil.ComponentStyle.SMALL), |
| new GridBagConstraints(1, 0, 1, 1, 1.0, 0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, |
| new Insets(5, 0, 2, 0), 0, 0)); |
| severityPanel.add(panel, new GridBagConstraints(0, 1, 2, 1, 0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, |
| new Insets(0, 0, 0, 0), 0, 0)); |
| severityPanelWeightY = 0.3; |
| } |
| myOptionsPanel.add(severityPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, severityPanelWeightY, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); |
| if (configPanelAnchor.getComponentCount() != 0) { |
| configPanelAnchor.setBorder(IdeBorderFactory.createTitledBorder("Options", false, new Insets(0, 0, 0, 0))); |
| } |
| if (configPanelAnchor.getComponentCount() != 0 || scopesNames.isEmpty()) { |
| myOptionsPanel.add(configPanelAnchor, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, |
| new Insets(0, 0, 0, 0), 0, 0)); |
| } |
| myOptionsPanel.revalidate(); |
| GuiUtils.enableChildren(myOptionsPanel, isThoughOneNodeEnabled(nodes)); |
| } |
| else { |
| initOptionsAndDescriptionPanel(); |
| } |
| myOptionsPanel.repaint(); |
| } |
| |
| private boolean isThoughOneNodeEnabled(final List<InspectionConfigTreeNode> nodes) { |
| final Project project = myProjectProfileManager.getProject(); |
| for (final InspectionConfigTreeNode node : nodes) { |
| final String toolId = node.getDefaultDescriptor().getKey().toString(); |
| if (mySelectedProfile.getTools(toolId, project).isEnabled()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private void updateOptionsAndDescriptionPanel() { |
| final TreePath[] paths = myTreeTable.getTree().getSelectionPaths(); |
| if (paths != null) { |
| updateOptionsAndDescriptionPanel(paths); |
| } else { |
| initOptionsAndDescriptionPanel(); |
| } |
| } |
| |
| private void initOptionsAndDescriptionPanel() { |
| myOptionsPanel.removeAll(); |
| try { |
| myBrowser.read(new StringReader(EMPTY_HTML), null); |
| } |
| catch (IOException e1) { |
| //Can't be |
| } |
| myOptionsPanel.validate(); |
| myOptionsPanel.repaint(); |
| } |
| |
| private static void setConfigPanel(final JPanel configPanelAnchor, final ScopeToolState state) { |
| configPanelAnchor.removeAll(); |
| final JComponent additionalConfigPanel = state.getAdditionalConfigPanel(); |
| if (additionalConfigPanel != null) { |
| configPanelAnchor.add(ScrollPaneFactory.createScrollPane(additionalConfigPanel, SideBorder.NONE)); |
| } |
| } |
| |
| private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String[] groupPath) { |
| InspectionConfigTreeNode currentRoot = root; |
| for (final String group : groupPath) { |
| currentRoot = getGroupNode(currentRoot, group); |
| } |
| return currentRoot; |
| } |
| |
| private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String group) { |
| final int childCount = root.getChildCount(); |
| for (int i = 0; i < childCount; i++) { |
| InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i); |
| if (group.equals(child.getUserObject())) { |
| return child; |
| } |
| } |
| InspectionConfigTreeNode child = new InspectionConfigTreeNode(group); |
| root.add(child); |
| return child; |
| } |
| |
| public boolean setSelectedProfileModified(boolean modified) { |
| mySelectedProfile.setModified(modified); |
| return modified; |
| } |
| |
| ModifiableModel getSelectedProfile() { |
| return mySelectedProfile; |
| } |
| |
| private void setSelectedProfile(final ModifiableModel modifiableModel) { |
| if (mySelectedProfile == modifiableModel) return; |
| mySelectedProfile = (InspectionProfileImpl)modifiableModel; |
| if (mySelectedProfile != null) { |
| myInitialProfile = mySelectedProfile.getName(); |
| } |
| initToolStates(); |
| filterTree(); |
| } |
| |
| @Override |
| public Dimension getPreferredSize() { |
| return new Dimension(700, 500); |
| } |
| |
| public void disposeUI() { |
| if (myInspectionProfilePanel == null) { |
| return; |
| } |
| myProperties.setFloat(VERTICAL_DIVIDER_PROPORTION, myMainSplitter.getProportion()); |
| myProperties.setFloat(HORIZONTAL_DIVIDER_PROPORTION, myRightSplitter.getProportion()); |
| myAlarm.cancelAllRequests(); |
| myProfileFilter.dispose(); |
| if (mySelectedProfile != null) { |
| for (ScopeToolState state : mySelectedProfile.getAllTools(myProjectProfileManager.getProject())) { |
| state.resetConfigPanel(); |
| } |
| } |
| mySelectedProfile = null; |
| } |
| |
| private JPanel createInspectionProfileSettingsPanel() { |
| |
| myBrowser = new JEditorPane(UIUtil.HTML_MIME, EMPTY_HTML); |
| myBrowser.setEditable(false); |
| myBrowser.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| myBrowser.addHyperlinkListener(new BrowserHyperlinkListener()); |
| |
| initToolStates(); |
| fillTreeData(myProfileFilter != null ? myProfileFilter.getFilter() : null, true); |
| |
| JPanel descriptionPanel = new JPanel(new BorderLayout()); |
| descriptionPanel.setBorder(IdeBorderFactory.createTitledBorder(InspectionsBundle.message("inspection.description.title"), false, |
| new Insets(13, 0, 0, 0))); |
| descriptionPanel.add(ScrollPaneFactory.createScrollPane(myBrowser), BorderLayout.CENTER); |
| |
| myRightSplitter = new Splitter(true); |
| myRightSplitter.setFirstComponent(descriptionPanel); |
| myRightSplitter.setProportion(myProperties.getFloat(HORIZONTAL_DIVIDER_PROPORTION, 0.5f)); |
| |
| myOptionsPanel = new JPanel(new GridBagLayout()); |
| initOptionsAndDescriptionPanel(); |
| myRightSplitter.setSecondComponent(myOptionsPanel); |
| myRightSplitter.setHonorComponentsMinimumSize(true); |
| |
| final JPanel treePanel = new JPanel(new BorderLayout()); |
| final JScrollPane tree = initTreeScrollPane(); |
| treePanel.add(tree, BorderLayout.CENTER); |
| |
| final JPanel northPanel = new JPanel(new GridBagLayout()); |
| northPanel.setBorder(IdeBorderFactory.createEmptyBorder(2, 0, 2, 0)); |
| northPanel.add(myProfileFilter, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.BASELINE_TRAILING, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); |
| northPanel.add(createTreeToolbarPanel().getComponent(), new GridBagConstraints(1, 0, 1, 1, 0.5, 1, GridBagConstraints.BASELINE_LEADING, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); |
| treePanel.add(northPanel, BorderLayout.NORTH); |
| |
| myMainSplitter = new Splitter(false, myProperties.getFloat(VERTICAL_DIVIDER_PROPORTION, 0.5f), 0.01f, 0.99f); |
| myMainSplitter.setFirstComponent(treePanel); |
| myMainSplitter.setSecondComponent(myRightSplitter); |
| myMainSplitter.setHonorComponentsMinimumSize(false); |
| |
| final JPanel panel = new JPanel(new BorderLayout()); |
| panel.add(myMainSplitter, BorderLayout.CENTER); |
| return panel; |
| } |
| |
| public boolean isModified() { |
| if (myModified) return true; |
| if (mySelectedProfile.isChanged()) return true; |
| if (myShareProfile != (mySelectedProfile.getProfileManager() == myProjectProfileManager)) return true; |
| if (!Comparing.strEqual(myInitialProfile, mySelectedProfile.getName())) return true; |
| if (!Comparing.equal(myInitialScopesOrder, mySelectedProfile.getScopesOrder())) return true; |
| if (descriptorsAreChanged()) { |
| return true; |
| } |
| return false; |
| } |
| |
| public void reset() { |
| myModified = false; |
| setSelectedProfile(mySelectedProfile); |
| final String filter = myProfileFilter.getFilter(); |
| myProfileFilter.reset(); |
| myProfileFilter.setSelectedItem(filter); |
| myShareProfile = mySelectedProfile.getProfileManager() == myProjectProfileManager; |
| } |
| |
| public void apply() throws ConfigurationException { |
| final boolean modified = isModified(); |
| if (!modified) { |
| return; |
| } |
| final ModifiableModel selectedProfile = getSelectedProfile(); |
| final ProfileManager profileManager = |
| myShareProfile ? myProjectProfileManager : InspectionProfileManager.getInstance(); |
| selectedProfile.setLocal(!myShareProfile); |
| if (selectedProfile.getProfileManager() != profileManager) { |
| if (selectedProfile.getProfileManager().getProfile(selectedProfile.getName(), false) != null) { |
| selectedProfile.getProfileManager().deleteProfile(selectedProfile.getName()); |
| } |
| copyUsedSeveritiesIfUndefined(selectedProfile, profileManager); |
| selectedProfile.setProfileManager(profileManager); |
| } |
| final InspectionProfile parentProfile = selectedProfile.getParentProfile(); |
| |
| if (((InspectionProfileManagerImpl)InspectionProfileManager.getInstance()).getSchemesManager().isShared(selectedProfile)) { |
| if (descriptorsAreChanged()) { |
| throw new ConfigurationException("Shared profile cannot be modified. Please do \"Save As...\" first."); |
| } |
| |
| } |
| |
| try { |
| selectedProfile.commit(); |
| } |
| catch (IOException e) { |
| throw new ConfigurationException(e.getMessage()); |
| } |
| setSelectedProfile(parentProfile.getModifiableModel()); |
| setSelectedProfileModified(false); |
| myModified = false; |
| } |
| |
| private static void copyUsedSeveritiesIfUndefined(final ModifiableModel selectedProfile, final ProfileManager profileManager) { |
| final SeverityRegistrar registrar = ((SeverityProvider)profileManager).getSeverityRegistrar(); |
| final Set<HighlightSeverity> severities = ((InspectionProfileImpl)selectedProfile).getUsedSeverities(); |
| for (Iterator<HighlightSeverity> iterator = severities.iterator(); iterator.hasNext();) { |
| HighlightSeverity severity = iterator.next(); |
| if (registrar.isSeverityValid(severity.getName())) { |
| iterator.remove(); |
| } |
| } |
| |
| if (!severities.isEmpty()) { |
| final SeverityRegistrar oppositeRegister = ((SeverityProvider)selectedProfile.getProfileManager()).getSeverityRegistrar(); |
| for (HighlightSeverity severity : severities) { |
| final TextAttributesKey attributesKey = TextAttributesKey.find(severity.getName()); |
| final TextAttributes textAttributes = oppositeRegister.getTextAttributesBySeverity(severity); |
| LOG.assertTrue(textAttributes != null, severity); |
| HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(severity, attributesKey); |
| registrar.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info), |
| textAttributes.getErrorStripeColor()); |
| } |
| } |
| } |
| |
| private boolean descriptorsAreChanged() { |
| for (ToolDescriptors toolDescriptors : myInitialToolDescriptors) { |
| Descriptor desc = toolDescriptors.getDefaultDescriptor(); |
| Project project = myProjectProfileManager.getProject(); |
| if (mySelectedProfile.isToolEnabled(desc.getKey(), null, project) != desc.isEnabled()){ |
| return true; |
| } |
| if (mySelectedProfile.getErrorLevel(desc.getKey(), desc.getScope(), project) != desc.getLevel()) { |
| return true; |
| } |
| final List<Descriptor> descriptors = toolDescriptors.getNonDefaultDescriptors(); |
| for (Descriptor descriptor : descriptors) { |
| if (mySelectedProfile.isToolEnabled(descriptor.getKey(), descriptor.getScope(), project) != descriptor.isEnabled()) { |
| return true; |
| } |
| if (mySelectedProfile.getErrorLevel(descriptor.getKey(), descriptor.getScope(), project) != descriptor.getLevel()) { |
| return true; |
| } |
| } |
| |
| final List<ScopeToolState> tools = mySelectedProfile.getNonDefaultTools(desc.getKey().toString(), project); |
| if (tools.size() != descriptors.size()) { |
| return true; |
| } |
| for (int i = 0; i < tools.size(); i++) { |
| final ScopeToolState pair = tools.get(i); |
| if (!Comparing.equal(pair.getScope(project), descriptors.get(i).getScope())) { |
| return true; |
| } |
| } |
| } |
| |
| |
| return false; |
| } |
| |
| public boolean isProfileShared() { |
| return myShareProfile; |
| } |
| |
| public void setProfileShared(boolean profileShared) { |
| myShareProfile = profileShared; |
| } |
| |
| @Override |
| public void setVisible(boolean aFlag) { |
| if (aFlag && myInspectionProfilePanel == null) { |
| initUI(); |
| } |
| super.setVisible(aFlag); |
| } |
| |
| private void setNewHighlightingLevel(@NotNull HighlightDisplayLevel level) { |
| final int[] rows = myTreeTable.getTree().getSelectionRows(); |
| final boolean showOptionsAndDescriptorPanels = rows != null && rows.length == 1; |
| for (int i = 0; rows != null && i < rows.length; i++) { |
| final InspectionConfigTreeNode node = (InspectionConfigTreeNode)myTreeTable.getTree().getPathForRow(rows[i]).getLastPathComponent(); |
| final InspectionConfigTreeNode parent = (InspectionConfigTreeNode)node.getParent(); |
| final Object userObject = node.getUserObject(); |
| if (userObject instanceof ToolDescriptors && (node.getScopeName() != null || node.isLeaf())) { |
| updateErrorLevel(node, showOptionsAndDescriptorPanels, level); |
| updateUpHierarchy(node, parent); |
| } |
| else { |
| updateErrorLevelUpInHierarchy(level, showOptionsAndDescriptorPanels, node); |
| updateUpHierarchy(node, parent); |
| } |
| } |
| if (rows != null) { |
| updateOptionsAndDescriptionPanel(myTreeTable.getTree().getSelectionPaths()); |
| } |
| else { |
| initOptionsAndDescriptionPanel(); |
| } |
| repaintTableData(); |
| } |
| |
| private void updateErrorLevelUpInHierarchy(@NotNull HighlightDisplayLevel level, |
| boolean showOptionsAndDescriptorPanels, |
| InspectionConfigTreeNode node) { |
| node.dropCache(); |
| for (int j = 0; j < node.getChildCount(); j++) { |
| final InspectionConfigTreeNode child = (InspectionConfigTreeNode)node.getChildAt(j); |
| final Object userObject = child.getUserObject(); |
| if (userObject instanceof ToolDescriptors && (child.getScopeName() != null || child.isLeaf())) { |
| updateErrorLevel(child, showOptionsAndDescriptorPanels, level); |
| } |
| else { |
| updateErrorLevelUpInHierarchy(level, showOptionsAndDescriptorPanels, child); |
| } |
| } |
| } |
| |
| private void updateErrorLevel(final InspectionConfigTreeNode child, |
| final boolean showOptionsAndDescriptorPanels, |
| @NotNull HighlightDisplayLevel level) { |
| final HighlightDisplayKey key = child.getDefaultDescriptor().getKey(); |
| mySelectedProfile.setErrorLevel(key, level, null, myProjectProfileManager.getProject()); |
| child.dropCache(); |
| if (showOptionsAndDescriptorPanels) { |
| updateOptionsAndDescriptionPanel(new TreePath(child.getPath())); |
| } |
| } |
| |
| public JComponent getPreferredFocusedComponent() { |
| return myTreeTable; |
| } |
| |
| private class MyFilterComponent extends FilterComponent { |
| private MyFilterComponent() { |
| super(INSPECTION_FILTER_HISTORY, 10); |
| setHistory(Arrays.asList("\"New in 13\"")); |
| } |
| |
| @Override |
| public void filter() { |
| filterTree(getFilter()); |
| } |
| |
| @Override |
| protected void onlineFilter() { |
| if (mySelectedProfile == null) return; |
| final String filter = getFilter(); |
| getExpandedNodes(mySelectedProfile).saveVisibleState(myTreeTable.getTree()); |
| fillTreeData(filter, true); |
| reloadModel(); |
| if (filter == null || filter.isEmpty()) { |
| restoreTreeState(); |
| } else { |
| TreeUtil.expandAll(myTreeTable.getTree()); |
| } |
| } |
| } |
| } |