| /* |
| * 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.codeInspection.ex; |
| |
| import com.intellij.application.options.colors.ColorAndFontDescriptionPanel; |
| import com.intellij.application.options.colors.ColorAndFontOptions; |
| import com.intellij.application.options.colors.InspectionColorSettingsPage; |
| import com.intellij.application.options.colors.TextAttributesDescription; |
| import com.intellij.codeInsight.daemon.impl.HighlightInfoType; |
| import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; |
| import com.intellij.codeInsight.daemon.impl.SeverityUtil; |
| import com.intellij.codeInspection.InspectionsBundle; |
| import com.intellij.ide.DataManager; |
| import com.intellij.lang.annotation.HighlightSeverity; |
| import com.intellij.openapi.actionSystem.AnActionEvent; |
| import com.intellij.openapi.actionSystem.CommonDataKeys; |
| import com.intellij.openapi.actionSystem.DataContext; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.editor.colors.CodeInsightColors; |
| import com.intellij.openapi.editor.colors.EditorColorsScheme; |
| import com.intellij.openapi.editor.colors.TextAttributesKey; |
| import com.intellij.openapi.editor.markup.TextAttributes; |
| import com.intellij.openapi.options.Configurable; |
| import com.intellij.openapi.options.SearchableConfigurable; |
| import com.intellij.openapi.options.ShowSettingsUtil; |
| import com.intellij.openapi.options.ex.ConfigurableWrapper; |
| import com.intellij.openapi.options.newEditor.OptionsEditor; |
| import com.intellij.openapi.ui.DialogWrapper; |
| import com.intellij.openapi.ui.InputValidator; |
| import com.intellij.openapi.ui.Messages; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.ui.*; |
| import com.intellij.ui.components.JBList; |
| import org.jdom.Element; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| import java.awt.*; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.*; |
| import java.util.List; |
| |
| import static com.intellij.codeInsight.daemon.impl.SeverityRegistrar.SeverityBasedTextAttributes; |
| |
| /** |
| * User: anna |
| * Date: 24-Feb-2006 |
| */ |
| public class SeverityEditorDialog extends DialogWrapper { |
| private final JPanel myPanel; |
| |
| private final JList myOptionsList = new JBList(); |
| private final ColorAndFontDescriptionPanel myOptionsPanel = new ColorAndFontDescriptionPanel(); |
| |
| private SeverityBasedTextAttributes myCurrentSelection; |
| private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.SeverityEditorDialog"); |
| private final SeverityRegistrar mySeverityRegistrar; |
| private final CardLayout myCard; |
| private final JPanel myRightPanel; |
| @NonNls private static final String DEFAULT = "DEFAULT"; |
| @NonNls private static final String EDITABLE = "EDITABLE"; |
| |
| public SeverityEditorDialog(final JComponent parent, final HighlightSeverity severity, final SeverityRegistrar severityRegistrar) { |
| super(parent, true); |
| mySeverityRegistrar = severityRegistrar; |
| myOptionsList.setCellRenderer(new DefaultListCellRenderer() { |
| @Override |
| public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
| final Component rendererComponent = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
| if (value instanceof SeverityBasedTextAttributes) { |
| setText(((SeverityBasedTextAttributes)value).getSeverity().getName()); |
| } |
| return rendererComponent; |
| } |
| }); |
| myOptionsList.addListSelectionListener(new ListSelectionListener() { |
| @Override |
| public void valueChanged(ListSelectionEvent e) { |
| if (myCurrentSelection != null) { |
| apply(myCurrentSelection); |
| } |
| myCurrentSelection = (SeverityBasedTextAttributes)myOptionsList.getSelectedValue(); |
| if (myCurrentSelection != null) { |
| reset(myCurrentSelection); |
| myCard.show(myRightPanel, mySeverityRegistrar.isDefaultSeverity(myCurrentSelection.getSeverity()) ? DEFAULT : EDITABLE); |
| } |
| } |
| }); |
| myOptionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
| |
| JPanel leftPanel = ToolbarDecorator.createDecorator(myOptionsList) |
| .setAddAction(new AnActionButtonRunnable() { |
| @Override |
| public void run(AnActionButton button) { |
| final String name = Messages.showInputDialog(myPanel, InspectionsBundle.message("highlight.severity.create.dialog.name.label"), |
| InspectionsBundle.message("highlight.severity.create.dialog.title"), |
| Messages.getQuestionIcon(), |
| "", new InputValidator() { |
| @Override |
| public boolean checkInput(final String inputString) { |
| final ListModel listModel = myOptionsList.getModel(); |
| for (int i = 0; i < listModel.getSize(); i++) { |
| final String severityName = ((SeverityBasedTextAttributes)listModel.getElementAt(i)).getSeverity().myName; |
| if (Comparing.strEqual(severityName, inputString)) return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean canClose(final String inputString) { |
| return checkInput(inputString); |
| } |
| }); |
| if (name == null) return; |
| final TextAttributes textAttributes = CodeInsightColors.WARNINGS_ATTRIBUTES.getDefaultAttributes(); |
| HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(new HighlightSeverity(name, 50), |
| TextAttributesKey |
| .createTextAttributesKey(name)); |
| |
| SeverityBasedTextAttributes newSeverityBasedTextAttributes = new SeverityBasedTextAttributes(textAttributes.clone(), info); |
| ((DefaultListModel)myOptionsList.getModel()).addElement(newSeverityBasedTextAttributes); |
| |
| myOptionsList.clearSelection(); |
| ListScrollingUtil.selectItem(myOptionsList, newSeverityBasedTextAttributes); |
| } |
| }).setMoveUpAction(new AnActionButtonRunnable() { |
| @Override |
| public void run(AnActionButton button) { |
| apply(myCurrentSelection); |
| ListUtil.moveSelectedItemsUp(myOptionsList); |
| } |
| }).setMoveDownAction(new AnActionButtonRunnable() { |
| @Override |
| public void run(AnActionButton button) { |
| apply(myCurrentSelection); |
| ListUtil.moveSelectedItemsDown(myOptionsList); |
| } |
| }).createPanel(); |
| ToolbarDecorator.findRemoveButton(leftPanel).addCustomUpdater(new AnActionButtonUpdater() { |
| @Override |
| public boolean isEnabled(AnActionEvent e) { |
| return !mySeverityRegistrar |
| .isDefaultSeverity(((SeverityBasedTextAttributes)myOptionsList.getSelectedValue()).getSeverity()); |
| } |
| }); |
| ToolbarDecorator.findUpButton(leftPanel).addCustomUpdater(new AnActionButtonUpdater() { |
| @Override |
| public boolean isEnabled(AnActionEvent e) { |
| boolean canMove = ListUtil.canMoveSelectedItemsUp(myOptionsList); |
| if (canMove) { |
| SeverityBasedTextAttributes pair = |
| (SeverityBasedTextAttributes)myOptionsList.getSelectedValue(); |
| if (pair != null && mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) { |
| final int newPosition = myOptionsList.getSelectedIndex() - 1; |
| pair = (SeverityBasedTextAttributes)myOptionsList.getModel().getElementAt(newPosition); |
| if (mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) { |
| canMove = false; |
| } |
| } |
| } |
| |
| return canMove; |
| } |
| }); |
| ToolbarDecorator.findDownButton(leftPanel).addCustomUpdater(new AnActionButtonUpdater() { |
| @Override |
| public boolean isEnabled(AnActionEvent e) { |
| boolean canMove = ListUtil.canMoveSelectedItemsDown(myOptionsList); |
| if (canMove) { |
| SeverityBasedTextAttributes pair = |
| (SeverityBasedTextAttributes)myOptionsList.getSelectedValue(); |
| if (pair != null && mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) { |
| final int newPosition = myOptionsList.getSelectedIndex() + 1; |
| pair = (SeverityBasedTextAttributes)myOptionsList.getModel().getElementAt(newPosition); |
| if (mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) { |
| canMove = false; |
| } |
| } |
| } |
| |
| return canMove; |
| } |
| }); |
| |
| myPanel = new JPanel(new BorderLayout()); |
| myPanel.add(leftPanel, BorderLayout.CENTER); |
| myCard = new CardLayout(); |
| myRightPanel = new JPanel(myCard); |
| final JPanel disabled = new JPanel(new GridBagLayout()); |
| final JButton button = new JButton(InspectionsBundle.message("severities.default.settings.message")); |
| button.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(final ActionEvent e) { |
| editColorsAndFonts(); |
| } |
| }); |
| disabled.add(button, |
| new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, |
| 0)); |
| myRightPanel.add(DEFAULT, disabled); |
| myRightPanel.add(EDITABLE, myOptionsPanel); |
| myCard.show(myRightPanel, EDITABLE); |
| myPanel.add(myRightPanel, BorderLayout.EAST); |
| fillList(severity); |
| init(); |
| setTitle(InspectionsBundle.message("severities.editor.dialog.title")); |
| reset((SeverityBasedTextAttributes)myOptionsList.getSelectedValue()); |
| } |
| |
| private void editColorsAndFonts() { |
| final String toConfigure = getSelectedType().getSeverity(null).myName; |
| doOKAction(); |
| myOptionsList.clearSelection(); |
| final DataContext dataContext = DataManager.getInstance().getDataContext(myPanel); |
| final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(dataContext); |
| if (optionsEditor != null) { |
| final ColorAndFontOptions colorAndFontOptions = |
| (ColorAndFontOptions)((ConfigurableWrapper)optionsEditor.findConfigurableById(ColorAndFontOptions.ID)).getConfigurable(); |
| assert colorAndFontOptions != null; |
| final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class); |
| LOG.assertTrue(javaPage != null); |
| optionsEditor.clearSearchAndSelect(javaPage).doWhenDone(new Runnable() { |
| @Override |
| public void run() { |
| final Runnable runnable = javaPage.enableSearch(toConfigure); |
| if (runnable != null) { |
| SwingUtilities.invokeLater(runnable); |
| } |
| } |
| }); |
| } |
| else { |
| ColorAndFontOptions colorAndFontOptions = new ColorAndFontOptions(); |
| final Configurable[] configurables = colorAndFontOptions.buildConfigurables(); |
| try { |
| final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class); |
| LOG.assertTrue(javaPage != null); |
| ShowSettingsUtil.getInstance().editConfigurable(CommonDataKeys.PROJECT.getData(dataContext), javaPage); |
| } |
| finally { |
| for (Configurable configurable : configurables) { |
| configurable.disposeUIResources(); |
| } |
| colorAndFontOptions.disposeUIResources(); |
| } |
| } |
| } |
| |
| private void fillList(final HighlightSeverity severity) { |
| DefaultListModel model = new DefaultListModel(); |
| model.removeAllElements(); |
| final List<SeverityBasedTextAttributes> infoTypes = new ArrayList<SeverityBasedTextAttributes>(); |
| infoTypes.addAll(SeverityUtil.getRegisteredHighlightingInfoTypes(mySeverityRegistrar)); |
| Collections.sort(infoTypes, new Comparator<SeverityBasedTextAttributes>() { |
| @Override |
| public int compare(SeverityBasedTextAttributes attributes1, |
| SeverityBasedTextAttributes attributes2) { |
| return -mySeverityRegistrar.compare(attributes1.getSeverity(), attributes2.getSeverity()); |
| } |
| }); |
| SeverityBasedTextAttributes preselection = null; |
| for (SeverityBasedTextAttributes type : infoTypes) { |
| model.addElement(type); |
| if (type.getSeverity().equals(severity)) { |
| preselection = type; |
| } |
| } |
| myOptionsList.setModel(model); |
| myOptionsList.setSelectedValue(preselection, true); |
| } |
| |
| |
| private void apply(SeverityBasedTextAttributes info) { |
| final MyTextAttributesDescription description = |
| new MyTextAttributesDescription(info.getType().toString(), null, new TextAttributes(), info.getType().getAttributesKey()); |
| myOptionsPanel.apply(description, null); |
| @NonNls Element textAttributes = new Element("temp"); |
| try { |
| description.getTextAttributes().writeExternal(textAttributes); |
| info.getAttributes().readExternal(textAttributes); |
| } |
| catch (Exception e) { |
| LOG.error(e); |
| } |
| } |
| |
| private void reset(SeverityBasedTextAttributes info) { |
| if (info == null) { |
| return; |
| } |
| final MyTextAttributesDescription description = |
| new MyTextAttributesDescription(info.getType().toString(), null, info.getAttributes(), info.getType().getAttributesKey()); |
| @NonNls Element textAttributes = new Element("temp"); |
| try { |
| info.getAttributes().writeExternal(textAttributes); |
| description.getTextAttributes().readExternal(textAttributes); |
| } |
| catch (Exception e) { |
| LOG.error(e); |
| } |
| myOptionsPanel.reset(description); |
| } |
| |
| @Override |
| protected void doOKAction() { |
| apply((SeverityBasedTextAttributes)myOptionsList.getSelectedValue()); |
| final Collection<SeverityBasedTextAttributes> infoTypes = |
| new HashSet<SeverityBasedTextAttributes>(SeverityUtil.getRegisteredHighlightingInfoTypes(mySeverityRegistrar)); |
| final ListModel listModel = myOptionsList.getModel(); |
| final List<HighlightSeverity> order = new ArrayList<HighlightSeverity>(); |
| for (int i = listModel.getSize() - 1; i >= 0; i--) { |
| final SeverityBasedTextAttributes info = |
| (SeverityBasedTextAttributes)listModel.getElementAt(i); |
| order.add(info.getSeverity()); |
| if (!mySeverityRegistrar.isDefaultSeverity(info.getSeverity())) { |
| infoTypes.remove(info); |
| final Color stripeColor = info.getAttributes().getErrorStripeColor(); |
| mySeverityRegistrar.registerSeverity(info, stripeColor != null ? stripeColor : LightColors.YELLOW); |
| } |
| } |
| for (SeverityBasedTextAttributes info : infoTypes) { |
| mySeverityRegistrar.unregisterSeverity(info.getSeverity()); |
| } |
| mySeverityRegistrar.setOrder(order); |
| super.doOKAction(); |
| } |
| |
| @Override |
| @Nullable |
| protected JComponent createCenterPanel() { |
| return myPanel; |
| } |
| |
| @Nullable |
| public HighlightInfoType getSelectedType() { |
| final SeverityBasedTextAttributes selection = |
| (SeverityBasedTextAttributes)myOptionsList.getSelectedValue(); |
| return selection != null ? selection.getType() : null; |
| } |
| |
| private static class MyTextAttributesDescription extends TextAttributesDescription { |
| public MyTextAttributesDescription(final String name, |
| final String group, |
| final TextAttributes attributes, |
| final TextAttributesKey type) { |
| super(name, group, attributes, type, null, null, null); |
| } |
| |
| @Override |
| public void apply(EditorColorsScheme scheme) { |
| |
| } |
| |
| @Override |
| public boolean isErrorStripeEnabled() { |
| return true; |
| } |
| |
| |
| @Override |
| public TextAttributes getTextAttributes() { |
| return super.getTextAttributes(); |
| } |
| } |
| } |