ComponentWithBrowseButton - optional remove listener on hide
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInspection / ex / SeverityEditorDialog.java
blobf77107c9952bbbf1feaa53c6bc1688ad7785cffc
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.codeInspection.ex;
19 import com.intellij.application.options.colors.ColorAndFontDescriptionPanel;
20 import com.intellij.application.options.colors.ColorAndFontOptions;
21 import com.intellij.application.options.colors.InspectionColorSettingsPage;
22 import com.intellij.application.options.colors.TextAttributesDescription;
23 import com.intellij.application.options.editor.EditorOptionsProvider;
24 import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
25 import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
26 import com.intellij.codeInspection.InspectionsBundle;
27 import com.intellij.execution.ExecutionBundle;
28 import com.intellij.ide.DataManager;
29 import com.intellij.ide.IdeBundle;
30 import com.intellij.lang.annotation.HighlightSeverity;
31 import com.intellij.openapi.actionSystem.*;
32 import com.intellij.openapi.diagnostic.Logger;
33 import com.intellij.openapi.editor.colors.CodeInsightColors;
34 import com.intellij.openapi.editor.colors.EditorColorsScheme;
35 import com.intellij.openapi.editor.colors.TextAttributesKey;
36 import com.intellij.openapi.editor.markup.TextAttributes;
37 import com.intellij.openapi.extensions.Extensions;
38 import com.intellij.openapi.options.SearchableConfigurable;
39 import com.intellij.openapi.options.ShowSettingsUtil;
40 import com.intellij.openapi.options.newEditor.OptionsEditor;
41 import com.intellij.openapi.ui.DialogWrapper;
42 import com.intellij.openapi.ui.InputValidator;
43 import com.intellij.openapi.ui.Messages;
44 import com.intellij.openapi.util.Comparing;
45 import com.intellij.openapi.util.Condition;
46 import com.intellij.openapi.util.Factory;
47 import com.intellij.openapi.util.IconLoader;
48 import com.intellij.ui.LightColors;
49 import com.intellij.ui.ListUtil;
50 import com.intellij.ui.ReorderableListController;
51 import org.jdom.Element;
52 import org.jetbrains.annotations.NonNls;
53 import org.jetbrains.annotations.Nullable;
55 import javax.swing.*;
56 import javax.swing.event.ListSelectionEvent;
57 import javax.swing.event.ListSelectionListener;
58 import java.awt.*;
59 import java.awt.event.ActionEvent;
60 import java.awt.event.ActionListener;
61 import java.util.*;
62 import java.util.List;
64 /**
65 * User: anna
66 * Date: 24-Feb-2006
68 public class SeverityEditorDialog extends DialogWrapper {
69 private final JPanel myPanel;
71 private final JList myOptionsList = new JList();
72 private final ColorAndFontDescriptionPanel myOptionsPanel = new ColorAndFontDescriptionPanel();
74 private SeverityRegistrar.SeverityBasedTextAttributes myCurrentSelection;
75 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.SeverityEditorDialog");
76 private final SeverityRegistrar mySeverityRegistrar;
77 private final CardLayout myCard;
78 private final JPanel myRightPanel;
79 @NonNls private static final String DEFAULT = "DEFAULT";
80 @NonNls private static final String EDITABLE = "EDITABLE";
82 public SeverityEditorDialog(final JComponent parent, final HighlightSeverity severity, final SeverityRegistrar severityRegistrar) {
83 super(parent, true);
84 mySeverityRegistrar = severityRegistrar;
85 myOptionsList.setCellRenderer(new DefaultListCellRenderer() {
86 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
87 final Component rendererComponent = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
88 if (value instanceof SeverityRegistrar.SeverityBasedTextAttributes) {
89 setText(((SeverityRegistrar.SeverityBasedTextAttributes)value).getSeverity().toString());
91 return rendererComponent;
93 });
94 myOptionsList.addListSelectionListener(new ListSelectionListener() {
95 public void valueChanged(ListSelectionEvent e) {
96 if (myCurrentSelection != null) {
97 apply(myCurrentSelection);
99 myCurrentSelection = (SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getSelectedValue();
100 if (myCurrentSelection != null) {
101 reset(myCurrentSelection);
102 myCard.show(myRightPanel, mySeverityRegistrar.isDefaultSeverity(myCurrentSelection.getSeverity()) ? DEFAULT : EDITABLE);
106 myOptionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
107 JScrollPane scrollPane = new JScrollPane(myOptionsList);
108 scrollPane.setPreferredSize(new Dimension(230, 60));
109 JPanel leftPanel = new JPanel(new BorderLayout());
110 leftPanel.add(scrollPane, BorderLayout.CENTER);
111 leftPanel.add(createListToolbar(), BorderLayout.NORTH);
112 myPanel = new JPanel(new BorderLayout());
113 myPanel.add(leftPanel, BorderLayout.WEST);
114 myCard = new CardLayout();
115 myRightPanel = new JPanel(myCard);
116 final JPanel disabled = new JPanel(new GridBagLayout());
117 final JButton button = new JButton(InspectionsBundle.message("severities.default.settings.message"));
118 button.addActionListener(new ActionListener(){
119 public void actionPerformed(final ActionEvent e) {
120 final String toConfigure = getSelectedType().getSeverity(null).myName;
121 doOKAction();
122 myOptionsList.clearSelection();
123 ColorAndFontOptions colorAndFontOptions = null;
124 for (EditorOptionsProvider provider : Extensions.getExtensions(EditorOptionsProvider.EP_NAME)) {
125 if (provider.getClass().isAssignableFrom(ColorAndFontOptions.class)) {
126 colorAndFontOptions = (ColorAndFontOptions)provider;
127 break;
130 assert colorAndFontOptions != null;
131 final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class);
132 LOG.assertTrue(javaPage != null);
133 final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(DataManager.getInstance().getDataContext());
134 if (optionsEditor != null) {
135 optionsEditor.select(javaPage).doWhenDone(new Runnable(){
136 public void run() {
137 final Runnable runnable = javaPage.enableSearch(toConfigure);
138 if (runnable != null) {
139 SwingUtilities.invokeLater(runnable);
143 } else {
144 ShowSettingsUtil.getInstance().editConfigurable(PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()), javaPage);
148 disabled.add(button, new GridBagConstraints(0,0,1,1,0,0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0,0,0,0),0,0));
149 myRightPanel.add(DEFAULT, disabled);
150 myRightPanel.add(EDITABLE, myOptionsPanel);
151 myCard.show(myRightPanel, EDITABLE);
152 myPanel.add(myRightPanel, BorderLayout.CENTER);
153 fillList(severity);
154 init();
155 setTitle(InspectionsBundle.message("severities.editor.dialog.title"));
156 reset((SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getSelectedValue());
159 private void fillList(final HighlightSeverity severity) {
160 DefaultListModel model = new DefaultListModel();
161 model.removeAllElements();
162 final List<SeverityRegistrar.SeverityBasedTextAttributes> infoTypes = new ArrayList<SeverityRegistrar.SeverityBasedTextAttributes>();
163 infoTypes.addAll(mySeverityRegistrar.getRegisteredHighlightingInfoTypes());
164 Collections.sort(infoTypes, new Comparator<SeverityRegistrar.SeverityBasedTextAttributes>() {
165 public int compare(SeverityRegistrar.SeverityBasedTextAttributes attributes1, SeverityRegistrar.SeverityBasedTextAttributes attributes2) {
166 return - mySeverityRegistrar.compare(attributes1.getSeverity(), attributes2.getSeverity());
169 SeverityRegistrar.SeverityBasedTextAttributes preselection = null;
170 for (SeverityRegistrar.SeverityBasedTextAttributes type : infoTypes) {
171 model.addElement(type);
172 if (type.getSeverity().equals(severity)) {
173 preselection = type;
176 myOptionsList.setModel(model);
177 myOptionsList.setSelectedValue(preselection, true);
181 private void apply(SeverityRegistrar.SeverityBasedTextAttributes info) {
182 final MyTextAttributesDescription description =
183 new MyTextAttributesDescription(info.getType().toString(), null, new TextAttributes(), info.getType().getAttributesKey());
184 myOptionsPanel.apply(description, null);
185 @NonNls Element textAttributes = new Element("temp");
186 try {
187 description.getTextAttributes().writeExternal(textAttributes);
188 info.getAttributes().readExternal(textAttributes);
190 catch (Exception e) {
191 LOG.error(e);
195 private void reset(SeverityRegistrar.SeverityBasedTextAttributes info) {
196 final MyTextAttributesDescription description =
197 new MyTextAttributesDescription(info.getType().toString(), null, info.getAttributes(), info.getType().getAttributesKey());
198 @NonNls Element textAttributes = new Element("temp");
199 try {
200 info.getAttributes().writeExternal(textAttributes);
201 description.getTextAttributes().readExternal(textAttributes);
203 catch (Exception e) {
204 LOG.error(e);
206 myOptionsPanel.reset(description);
209 private JComponent createListToolbar() {
210 DefaultActionGroup group = new DefaultActionGroup();
211 final ReorderableListController<SeverityRegistrar.SeverityBasedTextAttributes> controller =
212 ReorderableListController.create(myOptionsList, group);
213 controller.addAddAction(IdeBundle.message("action.add"), new Factory<SeverityRegistrar.SeverityBasedTextAttributes>() {
214 @Nullable
215 public SeverityRegistrar.SeverityBasedTextAttributes create() {
216 final String name = Messages.showInputDialog(myPanel, InspectionsBundle.message("highlight.severity.create.dialog.name.label"),
217 InspectionsBundle.message("highlight.severity.create.dialog.title"), Messages.getQuestionIcon(),
218 "", new InputValidator() {
219 public boolean checkInput(final String inputString) {
220 final ListModel listModel = myOptionsList.getModel();
221 for (int i = 0; i < listModel.getSize(); i++) {
222 final String severityName = ((SeverityRegistrar.SeverityBasedTextAttributes)listModel.getElementAt(i)).getSeverity().myName;
223 if (Comparing.strEqual(severityName, inputString)) return false;
225 return true;
228 public boolean canClose(final String inputString) {
229 return checkInput(inputString);
232 if (name == null) return null;
233 final TextAttributes textAttributes = CodeInsightColors.WARNINGS_ATTRIBUTES.getDefaultAttributes();
234 HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(new HighlightSeverity(name, 50),
235 TextAttributesKey.createTextAttributesKey(name));
236 return new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info);
238 }, true);
239 final ReorderableListController<SeverityRegistrar.SeverityBasedTextAttributes>.RemoveActionDescription removeAction =
240 controller.addRemoveAction(IdeBundle.message("action.remove"));
241 removeAction.setEnableCondition(new Condition<SeverityRegistrar.SeverityBasedTextAttributes>() {
242 public boolean value(final SeverityRegistrar.SeverityBasedTextAttributes pair) {
243 return !mySeverityRegistrar.isDefaultSeverity(pair.getSeverity());
246 controller.addAction(new MyMoveUpAction());
247 controller.addAction(new MyMoveDownAction());
248 ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
249 return toolbar.getComponent();
253 protected void doOKAction() {
254 apply((SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getSelectedValue());
255 final Collection<SeverityRegistrar.SeverityBasedTextAttributes> infoTypes =
256 new HashSet<SeverityRegistrar.SeverityBasedTextAttributes>(mySeverityRegistrar.getRegisteredHighlightingInfoTypes());
257 final ListModel listModel = myOptionsList.getModel();
258 final List<String> order = new ArrayList<String>();
259 for (int i = listModel.getSize() - 1; i >= 0 ;i--) {
260 final SeverityRegistrar.SeverityBasedTextAttributes info =
261 (SeverityRegistrar.SeverityBasedTextAttributes)listModel.getElementAt(i);
262 order.add(info.getSeverity().myName);
263 if (!mySeverityRegistrar.isDefaultSeverity(info.getSeverity())) {
264 infoTypes.remove(info);
265 final Color stripeColor = info.getAttributes().getErrorStripeColor();
266 mySeverityRegistrar.registerSeverity(info, stripeColor != null ? stripeColor : LightColors.YELLOW);
269 for (SeverityRegistrar.SeverityBasedTextAttributes info : infoTypes) {
270 mySeverityRegistrar.unregisterSeverity(info.getSeverity());
272 mySeverityRegistrar.setOrder(order);
273 super.doOKAction();
276 @Nullable
277 protected JComponent createCenterPanel() {
278 return myPanel;
281 @Nullable
282 public HighlightInfoType getSelectedType() {
283 final SeverityRegistrar.SeverityBasedTextAttributes selection =
284 (SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getSelectedValue();
285 return selection != null ? selection.getType() : null;
288 private static class MyTextAttributesDescription extends TextAttributesDescription {
289 public MyTextAttributesDescription(final String name, final String group, final TextAttributes attributes, final TextAttributesKey type) {
290 super(name, group, attributes, type, null, null, null);
293 public void apply(EditorColorsScheme scheme) {
297 public boolean isErrorStripeEnabled() {
298 return true;
302 public TextAttributes getTextAttributes() {
303 return super.getTextAttributes();
307 private class MyMoveUpAction extends AnAction {
308 public MyMoveUpAction() {
309 super(ExecutionBundle.message("move.up.action.name"), null, IconLoader.getIcon("/actions/moveUp.png"));
312 public void actionPerformed(final AnActionEvent e) {
313 apply(myCurrentSelection);
314 ListUtil.moveSelectedItemsUp(myOptionsList);
317 public void update(final AnActionEvent e) {
318 boolean canMove = ListUtil.canMoveSelectedItemsUp(myOptionsList);
319 if (canMove) {
320 SeverityRegistrar.SeverityBasedTextAttributes pair =
321 (SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getSelectedValue();
322 if (pair != null && mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) {
323 final int newPosition = myOptionsList.getSelectedIndex() - 1;
324 pair = (SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getModel().getElementAt(newPosition);
325 if (mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) {
326 canMove = false;
330 e.getPresentation().setEnabled(canMove);
334 private class MyMoveDownAction extends AnAction {
335 public MyMoveDownAction() {
336 super(ExecutionBundle.message("move.down.action.name"), null, IconLoader.getIcon("/actions/moveDown.png"));
339 public void actionPerformed(final AnActionEvent e) {
340 apply(myCurrentSelection);
341 ListUtil.moveSelectedItemsDown(myOptionsList);
344 public void update(final AnActionEvent e) {
345 boolean canMove = ListUtil.canMoveSelectedItemsDown(myOptionsList);
346 if (canMove) {
347 SeverityRegistrar.SeverityBasedTextAttributes pair =
348 (SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getSelectedValue();
349 if (pair != null && mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) {
350 final int newPosition = myOptionsList.getSelectedIndex() + 1;
351 pair = (SeverityRegistrar.SeverityBasedTextAttributes)myOptionsList.getModel().getElementAt(newPosition);
352 if (mySeverityRegistrar.isDefaultSeverity(pair.getSeverity())) {
353 canMove = false;
357 e.getPresentation().setEnabled(canMove);