2 * Copyright 2000-2015 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.application.options.colors;
19 import com.intellij.ide.DataManager;
20 import com.intellij.ide.util.PropertiesComponent;
21 import com.intellij.openapi.editor.colors.EditorColorsScheme;
22 import com.intellij.openapi.options.SearchableConfigurable;
23 import com.intellij.openapi.options.ex.Settings;
24 import com.intellij.openapi.util.ActionCallback;
25 import com.intellij.ui.ScrollPaneFactory;
26 import com.intellij.util.EventDispatcher;
27 import com.intellij.util.ui.JBUI;
28 import org.jetbrains.annotations.NotNull;
31 import javax.swing.event.HyperlinkEvent;
32 import javax.swing.event.TreeSelectionEvent;
33 import javax.swing.event.TreeSelectionListener;
34 import javax.swing.text.BadLocationException;
35 import javax.swing.text.Element;
37 import java.awt.event.ActionEvent;
38 import java.util.EventListener;
39 import java.util.HashSet;
42 public class OptionsPanelImpl extends JPanel implements OptionsPanel {
43 public static final String SELECTED_COLOR_OPTION_PROPERTY = "selected.color.option.type";
45 private final ColorOptionsTree myOptionsTree;
46 private final ColorDescriptionPanel myOptionsPanel;
48 private final ColorAndFontOptions myOptions;
49 private final SchemesPanel mySchemesProvider;
50 private final String myCategoryName;
52 private final PropertiesComponent myProperties;
54 private final EventDispatcher<ColorAndFontSettingsListener> myDispatcher = EventDispatcher.create(ColorAndFontSettingsListener.class);
56 public OptionsPanelImpl(ColorAndFontOptions options,
57 SchemesPanel schemesProvider,
58 String categoryName) {
59 this(options, schemesProvider, categoryName, new ColorAndFontDescriptionPanel());
62 public OptionsPanelImpl(ColorAndFontOptions options,
63 SchemesPanel schemesProvider,
65 ColorDescriptionPanel optionsPanel) {
66 super(new BorderLayout());
68 mySchemesProvider = schemesProvider;
69 myCategoryName = categoryName;
70 myProperties = PropertiesComponent.getInstance();
72 myOptionsPanel = optionsPanel;
73 myOptionsPanel.addListener(new ColorDescriptionPanel.Listener() {
75 public void onSettingsChanged(ActionEvent e) {
76 myDispatcher.getMulticaster().settingsChanged();
80 public void onHyperLinkClicked(HyperlinkEvent e) {
81 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
82 Settings settings = Settings.KEY.getData(DataManager.getInstance().getDataContext(OptionsPanelImpl.this));
83 String attrName = e.getDescription();
84 Element element = e.getSourceElement();
87 pageName = element.getDocument().getText(element.getStartOffset(), element.getEndOffset() - element.getStartOffset());
89 catch (BadLocationException e1) {
92 final SearchableConfigurable page = myOptions.findSubConfigurable(pageName);
93 if (page != null && settings != null) {
94 Runnable runnable = page.enableSearch(attrName);
95 ActionCallback callback = settings.select(page);
96 if (runnable != null) callback.doWhenDone(runnable);
102 myOptionsTree = new ColorOptionsTree(myCategoryName);
104 myOptionsTree.addTreeSelectionListener(new TreeSelectionListener() {
106 public void valueChanged(TreeSelectionEvent e) {
107 if (!mySchemesProvider.areSchemesLoaded()) return;
108 processListValueChanged();
112 JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myOptionsTree);
113 add(scrollPane, BorderLayout.CENTER);
114 add(myOptionsPanel.getPanel(), BorderLayout.EAST);
119 public void addListener(ColorAndFontSettingsListener listener) {
120 myDispatcher.addListener(listener);
123 private void processListValueChanged() {
124 Object selectedValue = myOptionsTree.getSelectedValue();
125 ColorAndFontDescription description = selectedValue instanceof ColorAndFontDescription ? (ColorAndFontDescription)selectedValue : null;
126 if (description == null) {
127 if (selectedValue == null) {
128 String preselectedType = myProperties.getValue(SELECTED_COLOR_OPTION_PROPERTY);
129 if (preselectedType != null) {
130 myOptionsTree.selectOptionByType(preselectedType);
131 description = myOptionsTree.getSelectedDescriptor();
135 if (description != null) {
136 myProperties.setValue(SELECTED_COLOR_OPTION_PROPERTY, description.getType());
137 myOptionsPanel.reset(description);
138 myDispatcher.getMulticaster().selectedOptionChanged(description);
141 myOptionsPanel.resetDefault();
145 private void fillOptionsList() {
146 myOptionsTree.fillOptions(myOptions);
150 public JPanel getPanel() {
155 public void updateOptionsList() {
157 processListValueChanged();
161 public Runnable showOption(final String attributeDisplayName) {
162 return () -> myOptionsTree.selectOptionByName(attributeDisplayName);
166 public void applyChangesToScheme() {
167 ColorAndFontDescription descriptor = myOptionsTree.getSelectedDescriptor();
168 if (descriptor != null) {
169 myOptionsPanel.apply(descriptor, myOptions.getSelectedScheme());
174 public void selectOption(String attributeType) {
175 myOptionsTree.selectOptionByType(attributeType);
179 public Set<String> processListOptions() {
180 HashSet<String> result = new HashSet<>();
181 EditorSchemeAttributeDescriptor[] descriptions = myOptions.getCurrentDescriptions();
182 for (EditorSchemeAttributeDescriptor description : descriptions) {
183 if (description.getGroup().equals(myCategoryName)) {
184 result.add(description.toString());
190 public interface ColorDescriptionPanel {
192 JComponent getPanel();
196 void reset(@NotNull ColorAndFontDescription description);
198 void apply(@NotNull ColorAndFontDescription descriptor, EditorColorsScheme scheme);
200 void addListener(@NotNull Listener listener);
202 interface Listener extends EventListener {
203 void onSettingsChanged(ActionEvent e);
205 void onHyperLinkClicked(HyperlinkEvent e);