blob: e239678af0adc74ff08d35a332b1ae9590ae1239 [file] [log] [blame]
/*
* 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();
}
}
}