com.intellij.codeInspection.ex.SeverityEditorDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.codeInspection.ex.SeverityEditorDialog.java

Source

/*
 * Copyright 2000-2009 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.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().toString());
                }
                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 = optionsEditor
                    .findConfigurable(ColorAndFontOptions.class);
            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) {
        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();
        }
    }
}