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.editor.colors.EditorSchemeAttributeDescriptor;
24 import com.intellij.openapi.options.ex.Settings;
25 import com.intellij.openapi.util.ActionCallback;
26 import com.intellij.ui.ScrollPaneFactory;
27 import com.intellij.util.EventDispatcher;
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();
77 myOptions.getColorAndFontGlobalState().stateChanged();
81 public void onHyperLinkClicked(HyperlinkEvent e) {
82 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
83 Settings settings = Settings.KEY.getData(DataManager.getInstance().getDataContext(OptionsPanelImpl.this));
84 String attrName = e.getDescription();
85 Element element = e.getSourceElement();
88 pageName = element.getDocument().getText(element.getStartOffset(), element.getEndOffset() - element.getStartOffset());
90 catch (BadLocationException e1) {
93 final SearchableConfigurable page = myOptions.findSubConfigurable(pageName);
94 if (page != null && settings != null) {
95 Runnable runnable = page.enableSearch(attrName);
96 ActionCallback callback = settings.select(page);
97 if (runnable != null) callback.doWhenDone(runnable);
103 myOptions.getColorAndFontGlobalState().addListener(new ColorAndFontSettingsListener.Abstract() {
105 public void settingsChanged() {
106 if (!mySchemesProvider.areSchemesLoaded()) return;
107 if (myOptionsTree.getSelectedValue() != null) {
108 // update options & preview after global state change
109 processListValueChanged();
114 myOptionsTree = new ColorOptionsTree(myCategoryName);
116 myOptionsTree.addTreeSelectionListener(new TreeSelectionListener() {
118 public void valueChanged(TreeSelectionEvent e) {
119 if (!mySchemesProvider.areSchemesLoaded()) return;
120 processListValueChanged();
124 JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myOptionsTree);
125 add(scrollPane, BorderLayout.CENTER);
126 add(myOptionsPanel.getPanel(), BorderLayout.EAST);
131 public void addListener(ColorAndFontSettingsListener listener) {
132 myDispatcher.addListener(listener);
135 private void processListValueChanged() {
136 Object selectedValue = myOptionsTree.getSelectedValue();
137 EditorSchemeAttributeDescriptor description = selectedValue instanceof EditorSchemeAttributeDescriptor
138 ? (EditorSchemeAttributeDescriptor)selectedValue
140 if (description == null) {
141 if (selectedValue == null) {
142 String preselectedType = myProperties.getValue(SELECTED_COLOR_OPTION_PROPERTY);
143 if (preselectedType != null) {
144 myOptionsTree.selectOptionByType(preselectedType);
145 description = myOptionsTree.getSelectedDescriptor();
149 if (description != null) {
150 myProperties.setValue(SELECTED_COLOR_OPTION_PROPERTY, description.getType());
151 myOptionsPanel.reset(description);
152 myDispatcher.getMulticaster().selectedOptionChanged(description);
155 myOptionsPanel.resetDefault();
159 private void fillOptionsList() {
160 myOptionsTree.fillOptions(myOptions);
164 public JPanel getPanel() {
169 public void updateOptionsList() {
171 processListValueChanged();
175 public Runnable showOption(final String attributeDisplayName) {
176 return () -> myOptionsTree.selectOptionByName(attributeDisplayName);
180 public void applyChangesToScheme() {
181 EditorSchemeAttributeDescriptor descriptor = myOptionsTree.getSelectedDescriptor();
182 if (descriptor != null) {
183 myOptionsPanel.apply(descriptor, myOptions.getSelectedScheme());
188 public void selectOption(String attributeType) {
189 myOptionsTree.selectOptionByType(attributeType);
193 public Set<String> processListOptions() {
194 HashSet<String> result = new HashSet<>();
195 EditorSchemeAttributeDescriptor[] descriptions = myOptions.getCurrentDescriptions();
196 for (EditorSchemeAttributeDescriptor description : descriptions) {
197 if (description.getGroup().equals(myCategoryName)) {
198 result.add(description.toString());
204 public interface ColorDescriptionPanel {
206 JComponent getPanel();
210 void reset(@NotNull EditorSchemeAttributeDescriptor description);
212 void apply(@NotNull EditorSchemeAttributeDescriptor descriptor, EditorColorsScheme scheme);
214 void addListener(@NotNull Listener listener);
216 interface Listener extends EventListener {
217 void onSettingsChanged(ActionEvent e);
219 void onHyperLinkClicked(HyperlinkEvent e);