void () { if (isDisposed()) { return; } Collection<InspectionConfigTreeNode.Tool> nodes = myTreeTable.getSelectedToolNodes(); if (!nodes.isEmpty()) { final Project project = getProject(); final InspectionConfigTreeNode.Tool singleNode = myTreeTable.getStrictlySelectedToolNode(); final ScopeToolState toolState = singleNode != null ? myProfile.getToolDefaultState(singleNode.getDefaultDescriptor().getKey().toString(), project) : null; boolean showDefaultConfigurationOptions = toolState == null || toolState.getTool().getTool().showDefaultConfigurationOptions(); if (singleNode != null) { // Inspection tool node selected final Descriptor descriptor = singleNode.getDefaultDescriptor(); if (descriptor.loadDescription() != null) { // need this in order to correctly load plugin-supplied descriptions final Descriptor defaultDescriptor = singleNode.getDefaultDescriptor(); final String description = defaultDescriptor.loadDescription(); //NON-NLS final InspectionProfileEntry tool = defaultDescriptor.getToolWrapper().getTool(); try { if (description == null) throw new NullPointerException(); @NlsSafe String markedDescription = SearchUtil.markup(SettingsUtil.wrapWithPoweredByMessage(description, tool.getClass().getClassLoader()), myProfileFilter.getFilter()); DescriptionEditorPaneKt.readHTMLWithCodeHighlighting(myDescription, markedDescription, descriptor.getState().getTool().getLanguage()); } catch (Throwable t) { LOG.error("Failed to load description for: " + tool.getClass() + "; description: " + description, t); } } else { DescriptionEditorPaneKt.readHTML(myDescription, AnalysisBundle.message("inspections.settings.no.description.warning")); } } else { // Inspection group node selected showDescriptionForSelection(); } myOptionsPanel.removeAll(); JPanel severityPanel; final JPanel configPanelAnchor = new JPanel(new GridBagLayout()); final boolean showOptionPanel; final double severityPanelWeightY; final Set<String> scopesNames = new HashSet<>(); for (final InspectionConfigTreeNode.Tool node : nodes) { final List<ScopeToolState> nonDefaultTools = myProfile.getNonDefaultTools(node.getDefaultDescriptor().getKey().toString(), project); for (final ScopeToolState tool : nonDefaultTools) { scopesNames.add(tool.getScopeName()); } } ScopesAndSeveritiesTable scopesAndScopesAndSeveritiesTable; myOptionsLabel = new JBLabel(AnalysisBundle.message("inspections.settings.options.title")); if (scopesNames.isEmpty()) { final HighlightSeverity severity = ScopesAndSeveritiesTable.getSeverity( ContainerUtil.map(nodes, node -> node.getDefaultDescriptor().getState()) ); // Scope final ScopesChooser scopesChooser = new ScopesChooser(ContainerUtil.map(nodes, node -> node.getDefaultDescriptor()), myProfile, project, null) { @Override protected void onScopesOrderChanged() { updateRecursively(nodes, true); } @Override protected void onScopeAdded(@NotNull String scopeName) { updateRecursively(nodes, true); } }; final JComponent scopesChooserComponent = scopesChooser.createCustomComponent( scopesChooser.getTemplatePresentation(), ActionPlaces.UNKNOWN ); // Highlighting final HighlightingChooser highlightingChooser = new HighlightingChooser(myProfile.getProfileManager().getSeverityRegistrar()) { @Override void onKeyChosen(@NotNull TextAttributesKey key) { final List<InspectionConfigTreeNode.Tool> toUpdate = new SmartList<>(); for (final InspectionConfigTreeNode.Tool node : nodes) { final NamedScope scope = node.getDefaultDescriptor().getScope(); final boolean doUpdate = myProfile.getEditorAttributesKey(node.getKey(), scope, project) != key; if (doUpdate) { myProfile.setEditorAttributesKey(node.getKey().toString(), key.getExternalName(), null, project); toUpdate.add(node); } } updateRecursively(toUpdate, true); } }; final var highlightsChooserComponent = highlightingChooser.createCustomComponent( highlightingChooser.getTemplatePresentation(), ActionPlaces.UNKNOWN ); updateHighlightingChooser(nodes, project, highlightingChooser); // Severity final LevelChooserAction severityLevelChooser = new LevelChooserAction(myProfile.getProfileManager().getSeverityRegistrar(), includeDoNotShow(nodes)) { @Override protected void onChosen(final @NotNull HighlightSeverity severity) { final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity); final List<InspectionConfigTreeNode.Tool> toUpdate = new SmartList<>(); for (final InspectionConfigTreeNode.Tool node : nodes) { final HighlightDisplayKey key = node.getDefaultDescriptor().getKey(); final NamedScope scope = node.getDefaultDescriptor().getScope(); final boolean doUpdate = myProfile.getErrorLevel(key, scope, project) != level || myProfile.getEditorAttributesKey(key, scope, project) != null; if (doUpdate) { myProfile.setErrorLevel(key, level, null, project); myProfile.setEditorAttributesKey(node.getKey().toString(), null, null, project); updateHighlightingChooser(nodes, project, highlightingChooser); toUpdate.add(node); } } updateRecursively(toUpdate, false); } }; severityLevelChooser.setChosen(severity); final JComponent severityLevelChooserComponent = severityLevelChooser.createCustomComponent( severityLevelChooser.getTemplatePresentation(), ActionPlaces.UNKNOWN ); severityLevelChooserComponent.getInputMap(WHEN_IN_FOCUSED_WINDOW).put( KeyStroke.getKeyStroke(KeyEvent.VK_V, MnemonicHelper.getFocusAcceleratorKeyMask()), "changeSeverity" ); severityLevelChooserComponent.getActionMap().put("changeSeverity", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { final var button = (ComboBoxAction.ComboBoxButton)severityLevelChooserComponent; button.showPopup(); } }); ScopesPanel scopesPanel = new ScopesPanel(scopesChooserComponent, severityLevelChooserComponent, highlightsChooserComponent); severityPanel = scopesPanel.panel; if (toolState != null) { setConfigPanel(configPanelAnchor, toolState); myOptionsLabel.setText(AnalysisBundle.message("inspections.settings.options.title")); } scopesAndScopesAndSeveritiesTable = null; showOptionPanel = configPanelAnchor.getComponentCount() != 0; severityPanelWeightY = 0; } else { if (singleNode != null) { for (final Descriptor descriptor : singleNode.getDescriptors().getNonDefaultDescriptors()) { descriptor.loadConfig(); } } final var tableSettings = new ScopesAndSeveritiesTable.TableSettings(nodes, myProfile, project) { @Override protected void onScopeChosen(@NotNull final ScopeToolState state) { setConfigPanel(configPanelAnchor, state); configPanelAnchor.revalidate(); configPanelAnchor.repaint(); } @Override protected void onSettingsChanged() { updateRecursively(nodes, false); } @Override protected void onScopeAdded() { updateRecursively(nodes, false); } @Override protected void onScopesOrderChanged() { updateRecursively(nodes, true); } @Override protected void onScopeRemoved(final int scopesCount) { updateRecursively(nodes, scopesCount == 1); } }; scopesAndScopesAndSeveritiesTable = new ScopesAndSeveritiesTable(tableSettings); final ToolbarDecorator wrappedTable = ToolbarDecorator .createDecorator(scopesAndScopesAndSeveritiesTable) .setToolbarPosition(ActionToolbarPosition.LEFT) .disableUpDownActions() .setAddIcon(LayeredIcon.ADD_WITH_DROPDOWN) .setRemoveActionUpdater( __ -> { final int selectedRow = scopesAndScopesAndSeveritiesTable.getSelectedRow(); final int rowCount = scopesAndScopesAndSeveritiesTable.getRowCount(); return rowCount - 1 != selectedRow; }) .addExtraAction(new AnActionButton(IdeBundle.messagePointer("action.Anonymous.text.edit.scopes.order"), AllIcons.General.GearPlain) { @Override public void actionPerformed(@NotNull AnActionEvent e) { final ScopesOrderDialog dlg = new ScopesOrderDialog(scopesAndScopesAndSeveritiesTable, myProfile, project); if (dlg.showAndGet()) { tableSettings.onScopesOrderChanged(); } } @Override public @NotNull ActionUpdateThread getActionUpdateThread() { return ActionUpdateThread.EDT; } }); severityPanel = wrappedTable.createPanel(); final Dimension panelSize = new Dimension(getMinimumSize().width, 81); severityPanel.setMinimumSize(panelSize); severityPanel.setPreferredSize(panelSize); severityPanel.setMaximumSize(panelSize); showOptionPanel = configPanelAnchor.getComponentCount() != 0; severityPanelWeightY = showOptionPanel ? 0 : 1; } final GridBag constraint = new GridBag() .setDefaultWeightX(1.0) .setDefaultWeightY(1.0); if (showDefaultConfigurationOptions) { myOptionsPanel.add(severityPanel, constraint.nextLine().weighty(severityPanelWeightY).fillCell().insetTop(SECTION_GAP)); } GuiUtils.enableChildren(myOptionsPanel, isThoughOneNodeEnabled(nodes)); if (showOptionPanel) { if (showDefaultConfigurationOptions) { myOptionsSeparator = new ToolOptionsSeparator(scopesAndScopesAndSeveritiesTable); myOptionsPanel.add(myOptionsSeparator, constraint.nextLine().weighty(0).fillCellHorizontally()); } myOptionsPanel.add(configPanelAnchor, constraint.nextLine().fillCell()); } else if (scopesNames.isEmpty()) { myOptionsPanel.add(configPanelAnchor, constraint.nextLine().fillCell()); } myOptionsPanel.revalidate(); } else { initOptionsAndDescriptionPanel(); final TreePath[] selectedPaths = myTreeTable.getTree().getSelectionPaths(); if (selectedPaths != null && selectedPaths.length > 0) { showDescriptionForSelection(); } } myOptionsPanel.repaint(); }