Revet color chemes API chages. Will be commited via "Remote run commit"
[fedora-idea.git] / lang-impl / src / com / intellij / application / options / colors / ColorAndFontOptions.java
blob5561943b78e5dee9d8691f404afd7c3a49053541
1 package com.intellij.application.options.colors;
3 import com.intellij.application.options.OptionsContainingConfigurable;
4 import com.intellij.application.options.editor.EditorOptionsProvider;
5 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
6 import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
7 import com.intellij.ide.DataManager;
8 import com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable;
9 import com.intellij.openapi.actionSystem.PlatformDataKeys;
10 import com.intellij.openapi.application.ApplicationBundle;
11 import com.intellij.openapi.diff.impl.settings.DiffOptionsPanel;
12 import com.intellij.openapi.diff.impl.settings.DiffPreviewPanel;
13 import com.intellij.openapi.editor.EditorFactory;
14 import com.intellij.openapi.editor.colors.ColorKey;
15 import com.intellij.openapi.editor.colors.EditorColorsManager;
16 import com.intellij.openapi.editor.colors.EditorColorsScheme;
17 import com.intellij.openapi.editor.colors.TextAttributesKey;
18 import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
19 import com.intellij.openapi.editor.colors.impl.DefaultColorsScheme;
20 import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl;
21 import com.intellij.openapi.editor.markup.EffectType;
22 import com.intellij.openapi.editor.markup.TextAttributes;
23 import com.intellij.openapi.options.Configurable;
24 import com.intellij.openapi.options.ConfigurationException;
25 import com.intellij.openapi.options.ExternalizableScheme;
26 import com.intellij.openapi.options.SearchableConfigurable;
27 import com.intellij.openapi.options.colors.AttributesDescriptor;
28 import com.intellij.openapi.options.colors.ColorDescriptor;
29 import com.intellij.openapi.options.colors.ColorSettingsPage;
30 import com.intellij.openapi.options.colors.ColorSettingsPages;
31 import com.intellij.openapi.options.newEditor.OptionsEditor;
32 import com.intellij.openapi.project.Project;
33 import com.intellij.openapi.project.ProjectManager;
34 import com.intellij.openapi.util.Comparing;
35 import com.intellij.openapi.util.IconLoader;
36 import com.intellij.openapi.util.Pair;
37 import com.intellij.openapi.vcs.FileStatus;
38 import com.intellij.openapi.vcs.FileStatusFactory;
39 import com.intellij.openapi.vcs.FileStatusManager;
40 import com.intellij.psi.search.scope.packageSet.NamedScope;
41 import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
42 import com.intellij.psi.search.scope.packageSet.PackageSet;
43 import com.intellij.util.containers.HashMap;
44 import gnu.trove.THashSet;
45 import gnu.trove.TObjectHashingStrategy;
46 import org.jetbrains.annotations.Nls;
47 import org.jetbrains.annotations.NotNull;
48 import org.jetbrains.annotations.Nullable;
50 import javax.swing.*;
51 import java.awt.*;
52 import java.awt.event.ActionEvent;
53 import java.awt.event.ActionListener;
54 import java.util.*;
55 import java.util.List;
57 public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract implements EditorOptionsProvider {
58 private HashMap<String,MyColorScheme> mySchemes;
59 private MyColorScheme mySelectedScheme;
60 public static final String DIFF_GROUP = ApplicationBundle.message("title.diff");
61 public static final String FILE_STATUS_GROUP = ApplicationBundle.message("title.file.status");
62 public static final String SCOPES_GROUP = ApplicationBundle.message("title.scope.based");
64 private boolean mySomeSchemesDeleted = false;
65 private Map<NewColorAndFontPanel, SearchableConfigurable> mySubPanels;
67 private SchemesPanel myRootSchemesPanel;
69 private boolean myInitResetCompleted = false;
70 private boolean myInitResetInvoked = false;
72 private boolean myRevertChangesCompleted = false;
74 private boolean myApplyCompleted = false;
75 private boolean myDisposeCompleted = false;
77 public boolean isModified() {
78 boolean listModified = isSchemeListModified();
79 boolean schemeModified = isSomeSchemeModified();
81 if (listModified || schemeModified) {
82 myApplyCompleted = false;
85 return listModified;
88 private boolean isSchemeListModified(){
89 if (mySomeSchemesDeleted) return true;
91 if (!mySelectedScheme.getName().equals(EditorColorsManager.getInstance().getGlobalScheme().getName())) return true;
93 for (MyColorScheme scheme : mySchemes.values()) {
94 if (scheme.isNew()) return true;
97 return false;
100 private boolean isSomeSchemeModified() {
101 for (MyColorScheme scheme : mySchemes.values()) {
102 if (scheme.isModified()) return true;
104 return false;
107 public EditorColorsScheme selectScheme(@NotNull String name) {
108 mySelectedScheme = getScheme(name);
109 return mySelectedScheme;
112 private MyColorScheme getScheme(String name) {
113 return mySchemes.get(name);
116 public EditorColorsScheme getSelectedScheme() {
117 return mySelectedScheme;
120 public EditorColorsScheme getOriginalSelectedScheme() {
121 return mySelectedScheme == null ? null : mySelectedScheme.getOriginalScheme();
124 public EditorSchemeAttributeDescriptor[] getCurrentDescriptions() {
125 return mySelectedScheme.getDescriptors();
128 public static boolean isDefault(EditorColorsScheme scheme) {
129 return ((MyColorScheme)scheme).isDefault();
132 public String[] getSchemeNames() {
133 ArrayList<MyColorScheme> schemes = new ArrayList<MyColorScheme>(mySchemes.values());
134 Collections.sort(schemes, new Comparator<MyColorScheme>() {
135 public int compare(MyColorScheme o1, MyColorScheme o2) {
136 if (isDefault(o1) && !isDefault(o2)) return -1;
137 if (!isDefault(o1) && isDefault(o2)) return 1;
139 return o1.getName().compareToIgnoreCase(o2.getName());
143 ArrayList<String> names = new ArrayList<String>(schemes.size());
144 for (MyColorScheme scheme : schemes) {
145 names.add(scheme.getName());
148 return names.toArray(new String[names.size()]);
151 public Collection<EditorColorsScheme> getSchemes() {
152 return new ArrayList<EditorColorsScheme>(mySchemes.values());
155 public void saveSchemeAs(String name) {
156 MyColorScheme scheme = mySelectedScheme;
157 if (scheme == null) return;
159 EditorColorsScheme clone = (EditorColorsScheme)scheme.getOriginalScheme().clone();
161 scheme.apply(clone);
163 clone.setName(name);
164 MyColorScheme newScheme = new MyColorScheme(clone);
165 initScheme(newScheme);
167 newScheme.setIsNew();
169 mySchemes.put(name, newScheme);
170 selectScheme(newScheme.getName());
171 resetSchemesCombo(null);
174 public void addImportedScheme(final EditorColorsScheme imported) {
175 MyColorScheme newScheme = new MyColorScheme(imported);
176 initScheme(newScheme);
178 mySchemes.put(imported.getName(), newScheme);
179 selectScheme(newScheme.getName());
180 resetSchemesCombo(null);
183 public void removeScheme(String name) {
184 if (mySelectedScheme.getName().equals(name)) {
185 //noinspection HardCodedStringLiteral
186 selectScheme("Default");
189 boolean deletedNewlyCreated = false;
191 MyColorScheme toDelete = mySchemes.get(name);
193 if (toDelete != null) {
194 deletedNewlyCreated = toDelete.isNew();
197 mySchemes.remove(name);
198 resetSchemesCombo(null);
199 mySomeSchemesDeleted = mySomeSchemesDeleted || !deletedNewlyCreated;
202 public void apply() throws ConfigurationException {
203 if (!myApplyCompleted) {
204 try {
205 EditorColorsManager myColorsManager = EditorColorsManager.getInstance();
207 myColorsManager.removeAllSchemes();
208 for (MyColorScheme scheme : mySchemes.values()) {
209 if (!scheme.isDefault()) {
210 scheme.apply();
211 myColorsManager.addColorsScheme(scheme.getOriginalScheme());
215 EditorColorsScheme originalScheme = mySelectedScheme.getOriginalScheme();
216 myColorsManager.setGlobalScheme(originalScheme);
218 applyChangesToEditors();
220 reset();
222 finally {
223 myApplyCompleted = true;
232 // initAll();
233 // resetSchemesCombo();
238 private void applyChangesToEditors() {
239 EditorFactory.getInstance().refreshAllEditors();
241 Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
242 for (Project openProject : openProjects) {
243 FileStatusManager.getInstance(openProject).fileStatusesChanged();
244 DaemonCodeAnalyzer.getInstance(openProject).restart();
248 private boolean myIsReset = false;
250 private void resetSchemesCombo(Object source) {
251 myIsReset = true;
252 try {
253 myRootSchemesPanel.resetSchemesCombo(source);
254 if (mySubPanels != null) {
255 for (NewColorAndFontPanel subPartialConfigurable : getPanels()) {
256 subPartialConfigurable.reset(source);
260 finally {
261 myIsReset = false;
265 @Override
266 public JComponent createComponent() {
267 if (myRootSchemesPanel == null) {
268 ensureSchemesPanel();
270 return myRootSchemesPanel;
273 @Override
274 public boolean hasOwnContent() {
275 return true;
278 protected Configurable[] buildConfigurables() {
279 myDisposeCompleted = false;
280 initAll();
282 ArrayList<NewColorAndFontPanel> panels = createSubPanels();
284 for (NewColorAndFontPanel partialConfigurable : panels) {
285 partialConfigurable.addSchemesListener(new ColorAndFontSettingsListener.Abstract(){
286 public void schemeChanged(final Object source) {
287 if (!myIsReset) {
288 resetSchemesCombo(source);
293 partialConfigurable.addDescriptionListener(new ColorAndFontSettingsListener.Abstract(){
294 @Override
295 public void fontChanged() {
296 for (NewColorAndFontPanel panel : getPanels()) {
297 panel.updatePreview();
304 List<Configurable> result = new ArrayList<Configurable>();
305 mySubPanels = new LinkedHashMap<NewColorAndFontPanel, SearchableConfigurable>(panels.size());
307 for (final NewColorAndFontPanel subPanel : panels) {
308 mySubPanels.put(subPanel, new InnerSearchableConfigurable(subPanel));
311 result.addAll(new ArrayList<SearchableConfigurable>(mySubPanels.values()));
313 return result.toArray(new Configurable[result.size()]);
316 private Set<NewColorAndFontPanel> getPanels() {
317 return mySubPanels.keySet();
320 private ArrayList<NewColorAndFontPanel> createSubPanels() {
322 ArrayList<NewColorAndFontPanel> result = new ArrayList<NewColorAndFontPanel>();
324 result.add(createFontConfigurable());
326 ColorSettingsPage[] pages = ColorSettingsPages.getInstance().getRegisteredPages();
327 for (ColorSettingsPage page : pages) {
328 final SimpleEditorPreview preview = new SimpleEditorPreview(this, page);
329 NewColorAndFontPanel panel = NewColorAndFontPanel.create(preview,
330 page.getDisplayName(),
331 this, null);
334 result.add(panel);
337 result.add(createDiffPanel());
339 result.add(NewColorAndFontPanel.create(new PreviewPanel.Empty(), ColorAndFontOptions.FILE_STATUS_GROUP, this, collectFileTypes()));
341 final JPanel scopePanel = createChooseScopePanel();
342 result.add(NewColorAndFontPanel.create(new PreviewPanel.Empty(){
343 public Component getPanel() {
345 return scopePanel;
348 }, ColorAndFontOptions.SCOPES_GROUP, this, null));
351 return result;
354 private Collection<String> collectFileTypes() {
355 ArrayList<String> result = new ArrayList<String>();
356 FileStatus[] statuses = FileStatusFactory.SERVICE.getInstance().getAllFileStatuses();
358 for (FileStatus status : statuses) {
359 result.add(status.getText());
361 return result;
364 private NewColorAndFontPanel createFontConfigurable() {
365 return new NewColorAndFontPanel(new SchemesPanel(this), new FontOptions(this), new FontEditorPreview(this), "Font", null){
366 @Override
367 public boolean containsFontOptions() {
368 return true;
373 private NewColorAndFontPanel createDiffPanel() {
374 final DiffPreviewPanel diffPreviewPanel = new DiffPreviewPanel();
375 diffPreviewPanel.setMergeRequest(null);
376 final DiffOptionsPanel optionsPanel = new DiffOptionsPanel(this);
378 optionsPanel.addListener(new ColorAndFontSettingsListener.Abstract(){
379 public void actionPerformed(final ActionEvent e) {
380 optionsPanel.applyChangesToScheme();
381 diffPreviewPanel.updateView();
386 SchemesPanel schemesPanel = new SchemesPanel(this);
388 schemesPanel.addListener(new ColorAndFontSettingsListener.Abstract(){
389 public void schemeChanged(final Object source) {
390 diffPreviewPanel.setColorScheme(getSelectedScheme());
391 optionsPanel.updateOptionsList();
392 diffPreviewPanel.updateView();
394 } );
396 return new NewColorAndFontPanel(schemesPanel, optionsPanel, diffPreviewPanel,ColorAndFontOptions.DIFF_GROUP, null);
400 private JPanel createChooseScopePanel() {
401 Project[] projects = ProjectManager.getInstance().getOpenProjects();
402 JPanel panel = new JPanel(new GridBagLayout());
403 //panel.setBorder(new LineBorder(Color.red));
404 if (projects.length == 0) return panel;
405 GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
406 new Insets(0, 0, 0, 0), 0, 0);
407 final Project contextProject = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
408 final Project project = contextProject != null ? contextProject : projects[0];
410 JButton button = new JButton(ApplicationBundle.message("button.edit.scopes"));
411 button.setPreferredSize(new Dimension(230, button.getPreferredSize().height));
412 panel.add(button, gc);
413 gc.gridx = GridBagConstraints.REMAINDER;
414 gc.weightx = 1;
415 panel.add(new JPanel(), gc);
417 gc.gridy++;
418 gc.gridx=0;
419 gc.weighty = 1;
420 panel.add(new JPanel(), gc);
421 button.addActionListener(new ActionListener() {
422 public void actionPerformed(ActionEvent e) {
423 final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(DataManager.getInstance().getDataContext());
424 if (optionsEditor != null) {
425 optionsEditor.select(ScopeChooserConfigurable.getInstance(project));
429 return panel;
433 private void initAll() {
434 EditorColorsManager colorsManager = EditorColorsManager.getInstance();
435 EditorColorsScheme[] allSchemes = colorsManager.getAllSchemes();
437 mySchemes = new HashMap<String, MyColorScheme>();
438 for (EditorColorsScheme allScheme : allSchemes) {
439 MyColorScheme schemeDelegate = new MyColorScheme(allScheme);
440 initScheme(schemeDelegate);
441 mySchemes.put(schemeDelegate.getName(), schemeDelegate);
444 mySelectedScheme = mySchemes.get(EditorColorsManager.getInstance().getGlobalScheme().getName());
445 assert mySelectedScheme != null : EditorColorsManager.getInstance().getGlobalScheme().getName() + "; myschemes=" + mySchemes;
448 private static void initScheme(MyColorScheme scheme) {
449 ArrayList<EditorSchemeAttributeDescriptor> descriptions = new ArrayList<EditorSchemeAttributeDescriptor>();
450 initPluggedDescriptions(descriptions, scheme);
451 initDiffDescriptors(descriptions, scheme);
452 initFileStatusDescriptors(descriptions, scheme);
453 initScopesDescriptors(descriptions, scheme);
455 scheme.setDescriptors(descriptions.toArray(new EditorSchemeAttributeDescriptor[descriptions.size()]));
458 private static void initPluggedDescriptions(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
459 ColorSettingsPage[] pages = ColorSettingsPages.getInstance().getRegisteredPages();
460 for (ColorSettingsPage page : pages) {
461 initDescriptions(page, descriptions, scheme);
465 private static void initDescriptions(ColorSettingsPage page,
466 ArrayList<EditorSchemeAttributeDescriptor> descriptions,
467 MyColorScheme scheme) {
468 String group = page.getDisplayName();
469 AttributesDescriptor[] attributeDescriptors = page.getAttributeDescriptors();
470 for (AttributesDescriptor descriptor : attributeDescriptors) {
471 addSchemedDescription(descriptions, descriptor.getDisplayName(), group, descriptor.getKey(), scheme, null, null);
474 ColorDescriptor[] colorDescriptors = page.getColorDescriptors();
475 for (ColorDescriptor descriptor : colorDescriptors) {
476 ColorKey back = descriptor.getKind() == ColorDescriptor.Kind.BACKGROUND ? descriptor.getKey() : null;
477 ColorKey fore = descriptor.getKind() == ColorDescriptor.Kind.FOREGROUND ? descriptor.getKey() : null;
478 addEditorSettingDescription(descriptions, descriptor.getDisplayName(), group, back, fore, scheme);
482 private static void initDiffDescriptors(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
483 DiffOptionsPanel.addSchemeDescriptions(descriptions, scheme);
486 private static void initFileStatusDescriptors(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
488 FileStatus[] statuses = FileStatusFactory.SERVICE.getInstance().getAllFileStatuses();
490 for (FileStatus fileStatus : statuses) {
491 addEditorSettingDescription(descriptions,
492 fileStatus.getText(),
493 FILE_STATUS_GROUP,
494 null,
495 fileStatus.getColorKey(),
496 scheme);
500 private static void initScopesDescriptors(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
501 Set<Pair<NamedScope,NamedScopesHolder>> namedScopes = new THashSet<Pair<NamedScope,NamedScopesHolder>>(new TObjectHashingStrategy<Pair<NamedScope,NamedScopesHolder>>() {
502 public int computeHashCode(final Pair<NamedScope, NamedScopesHolder> object) {
503 return object.getFirst().getName().hashCode();
506 public boolean equals(final Pair<NamedScope, NamedScopesHolder> o1, final Pair<NamedScope, NamedScopesHolder> o2) {
507 return o1.getFirst().getName().equals(o2.getFirst().getName());
510 Project[] projects = ProjectManager.getInstance().getOpenProjects();
511 for (Project project : projects) {
512 DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
513 List<Pair<NamedScope,NamedScopesHolder>> cachedScopes = codeAnalyzer.getScopeBasedHighlightingCachedScopes();
514 namedScopes.addAll(cachedScopes);
517 List<Pair<NamedScope, NamedScopesHolder>> list = new ArrayList<Pair<NamedScope, NamedScopesHolder>>(namedScopes);
519 Collections.sort(list, new Comparator<Pair<NamedScope,NamedScopesHolder>>() {
520 public int compare(final Pair<NamedScope,NamedScopesHolder> o1, final Pair<NamedScope,NamedScopesHolder> o2) {
521 return o1.getFirst().getName().compareToIgnoreCase(o2.getFirst().getName());
524 for (Pair<NamedScope,NamedScopesHolder> pair : list) {
525 NamedScope namedScope = pair.getFirst();
526 String name = namedScope.getName();
527 TextAttributesKey textAttributesKey = getScopeTextAttributeKey(name);
528 if (scheme.getAttributes(textAttributesKey) == null) {
529 scheme.setAttributes(textAttributesKey, new TextAttributes());
531 NamedScopesHolder holder = pair.getSecond();
533 PackageSet value = namedScope.getValue();
534 String toolTip = holder.getDisplayName() + (value==null ? "" : ": "+ value.getText());
535 addSchemedDescription(descriptions,
536 name,
537 SCOPES_GROUP,
538 textAttributesKey,
539 scheme, holder.getIcon(), toolTip);
543 public static TextAttributesKey getScopeTextAttributeKey(final String scope) {
544 return TextAttributesKey.find("SCOPE_KEY_" + scope);
547 private static void addEditorSettingDescription(ArrayList<EditorSchemeAttributeDescriptor> array,
548 String name,
549 String group,
550 ColorKey backgroundKey,
551 ColorKey foregroundKey,
552 EditorColorsScheme scheme) {
553 String type = null;
554 if (foregroundKey != null) {
555 type = foregroundKey.getExternalName();
557 else {
558 if (backgroundKey != null) {
559 type = backgroundKey.getExternalName();
562 ColorAndFontDescription descr = new EditorSettingColorDescription(name, group, backgroundKey, foregroundKey, type, scheme);
563 array.add(descr);
566 private static void addSchemedDescription(ArrayList<EditorSchemeAttributeDescriptor> array, String name, String group, TextAttributesKey key,
567 EditorColorsScheme scheme,
568 Icon icon,
569 String toolTip) {
570 ColorAndFontDescription descr = new SchemeTextAttributesDescription(name, group, key, scheme, icon, toolTip);
571 array.add(descr);
574 public String getDisplayName() {
575 return ApplicationBundle.message("title.colors.and.fonts");
578 public Icon getIcon() {
579 return IconLoader.getIcon("/general/configurableColorsAndFonts.png");
582 private void revertChanges(){
583 if (isSchemeListModified() || isSomeSchemeModified()) {
584 myRevertChangesCompleted = false;
587 if (!myRevertChangesCompleted) {
588 ensureSchemesPanel();
591 try {
592 resetImpl();
594 finally {
595 myRevertChangesCompleted = true;
601 private void resetImpl() {
602 mySomeSchemesDeleted = false;
603 initAll();
604 resetSchemesCombo(null);
607 public void reset() {
608 if (!myInitResetInvoked) {
609 super.reset();
610 if (!myInitResetCompleted) {
611 ensureSchemesPanel();
613 try {
614 resetImpl();
616 finally {
617 myInitResetCompleted = true;
621 myInitResetInvoked = true;
623 else {
624 revertChanges();
629 public void resetFromChild() {
630 if (!myInitResetCompleted) {
631 ensureSchemesPanel();
634 try {
635 resetImpl();
637 finally {
638 myInitResetCompleted = true;
644 private void ensureSchemesPanel() {
645 if (myRootSchemesPanel == null) {
646 myRootSchemesPanel = new SchemesPanel(this);
648 myRootSchemesPanel.addListener(new ColorAndFontSettingsListener.Abstract(){
649 @Override
650 public void schemeChanged(final Object source) {
651 if (!myIsReset) {
652 resetSchemesCombo(source);
660 public void disposeUIResources() {
661 if (!myDisposeCompleted) {
662 try {
663 super.disposeUIResources();
664 if (mySubPanels != null) {
665 for (NewColorAndFontPanel subPanel : getPanels()) {
666 subPanel.disposeUIResources();
669 if (myRootSchemesPanel != null) {
670 myRootSchemesPanel.disposeUIResources();
673 finally {
674 myDisposeCompleted = true;
677 mySubPanels = null;
679 myInitResetCompleted = false;
680 myInitResetInvoked = false;
681 myRevertChangesCompleted = false;
683 myApplyCompleted = false;
684 myRootSchemesPanel = null;
687 public boolean currentSchemeIsDefault() {
688 return mySelectedScheme.isDefault();
691 public boolean currentSchemeIsShared() {
692 return ColorSettingsUtil.isSharedScheme(mySelectedScheme);
696 private static class SchemeTextAttributesDescription extends TextAttributesDescription {
697 private TextAttributes myAttributesToApply;
698 private TextAttributesKey key;
700 public SchemeTextAttributesDescription(String name, String group, TextAttributesKey key, EditorColorsScheme scheme, Icon icon,
701 String toolTip) {
702 super(name, group,
703 scheme.getAttributes(key) == null
704 ? new TextAttributes()
705 : scheme.getAttributes(key).clone(),
706 key, scheme, icon, toolTip);
707 this.key = key;
708 myAttributesToApply = scheme.getAttributes(key);
709 initCheckedStatus();
712 public void apply(EditorColorsScheme scheme) {
713 if (scheme == null) scheme = getScheme();
714 if (myAttributesToApply != null) {
715 scheme.setAttributes(key, getTextAttributes());
719 public boolean isModified() {
720 return !Comparing.equal(myAttributesToApply, getTextAttributes());
723 public boolean isErrorStripeEnabled() {
724 return true;
728 private static class GetSetColor {
729 private final ColorKey myKey;
730 private EditorColorsScheme myScheme;
731 private boolean isModified = false;
732 private Color myColor;
734 public GetSetColor(ColorKey key, EditorColorsScheme scheme) {
735 myKey = key;
736 myScheme = scheme;
737 myColor = myScheme.getColor(myKey);
740 public Color getColor() {
741 return myColor;
744 public void setColor(Color col) {
745 if (getColor() == null || !getColor().equals(col)) {
746 isModified = true;
747 myColor = col;
751 public void apply(EditorColorsScheme scheme) {
752 if (scheme == null) scheme = myScheme;
753 scheme.setColor(myKey, myColor);
756 public boolean isModified() {
757 return isModified;
761 private static class EditorSettingColorDescription extends ColorAndFontDescription {
762 private GetSetColor myGetSetForeground;
763 private GetSetColor myGetSetBackground;
765 public EditorSettingColorDescription(String name,
766 String group,
767 ColorKey backgroundKey,
768 ColorKey foregroundKey,
769 String type,
770 EditorColorsScheme scheme) {
771 super(name, group, type, scheme, null, null);
772 if (backgroundKey != null) {
773 myGetSetBackground = new GetSetColor(backgroundKey, scheme);
775 if (foregroundKey != null) {
776 myGetSetForeground = new GetSetColor(foregroundKey, scheme);
778 initCheckedStatus();
781 public int getFontType() {
782 return 0;
785 public void setFontType(int type) {
788 public Color getExternalEffectColor() {
789 return null;
792 public void setExternalEffectColor(Color color) {
795 public void setExternalEffectType(EffectType type) {
798 public EffectType getExternalEffectType() {
799 return EffectType.LINE_UNDERSCORE;
802 public Color getExternalForeground() {
803 if (myGetSetForeground == null) {
804 return null;
806 return myGetSetForeground.getColor();
809 public void setExternalForeground(Color col) {
810 if (myGetSetForeground == null) {
811 return;
813 myGetSetForeground.setColor(col);
816 public Color getExternalBackground() {
817 if (myGetSetBackground == null) {
818 return null;
820 return myGetSetBackground.getColor();
823 public void setExternalBackground(Color col) {
824 if (myGetSetBackground == null) {
825 return;
827 myGetSetBackground.setColor(col);
830 public Color getExternalErrorStripe() {
831 return null;
834 public void setExternalErrorStripe(Color col) {
837 public boolean isFontEnabled() {
838 return false;
841 public boolean isForegroundEnabled() {
842 return myGetSetForeground != null;
845 public boolean isBackgroundEnabled() {
846 return myGetSetBackground != null;
849 public boolean isEffectsColorEnabled() {
850 return false;
853 public boolean isModified() {
854 return myGetSetBackground != null && myGetSetBackground.isModified()
855 || myGetSetForeground != null && myGetSetForeground.isModified();
858 public void apply(EditorColorsScheme scheme) {
859 if (myGetSetBackground != null) {
860 myGetSetBackground.apply(scheme);
862 if (myGetSetForeground != null) {
863 myGetSetForeground.apply(scheme);
868 public String getHelpTopic() {
869 return "reference.settingsdialog.IDE.editor.colors";
872 private static class MyColorScheme extends EditorColorsSchemeImpl {
873 private int myFontSize;
874 private float myLineSpacing;
875 private String myFontName;
876 private EditorSchemeAttributeDescriptor[] myDescriptors;
877 private String myName;
878 private boolean myIsNew = false;
880 public MyColorScheme(EditorColorsScheme parenScheme) {
881 super(parenScheme, DefaultColorSchemesManager.getInstance());
882 myFontSize = parenScheme.getEditorFontSize();
883 myLineSpacing = parenScheme.getLineSpacing();
884 myFontName = parenScheme.getEditorFontName();
885 myName = parenScheme.getName();
886 if (parenScheme instanceof ExternalizableScheme) {
887 getExternalInfo().copy(((ExternalizableScheme)parenScheme).getExternalInfo());
889 initFonts();
892 public String getName() {
893 return myName;
896 public void setName(String name) {
897 myName = name;
900 public void setDescriptors(EditorSchemeAttributeDescriptor[] descriptors) {
901 myDescriptors = descriptors;
904 public EditorSchemeAttributeDescriptor[] getDescriptors() {
905 return myDescriptors;
908 public boolean isDefault() {
909 return myParentScheme instanceof DefaultColorsScheme;
912 public boolean isModified() {
913 if (isFontModified()) return true;
915 for (EditorSchemeAttributeDescriptor descriptor : myDescriptors) {
916 if (descriptor.isModified()) {
917 return true;
921 return false;
924 private boolean isFontModified() {
925 if (myFontSize != myParentScheme.getEditorFontSize()) return true;
926 if (myLineSpacing != myParentScheme.getLineSpacing()) return true;
927 if (!myFontName.equals(myParentScheme.getEditorFontName())) return true;
928 return false;
931 public void apply() {
932 apply(myParentScheme);
935 public void apply(EditorColorsScheme scheme) {
936 scheme.setEditorFontSize(myFontSize);
937 scheme.setEditorFontName(myFontName);
938 scheme.setLineSpacing(myLineSpacing);
940 for (EditorSchemeAttributeDescriptor descriptor : myDescriptors) {
941 descriptor.apply(scheme);
945 public String getEditorFontName() {
946 return myFontName;
949 public int getEditorFontSize() {
950 return myFontSize;
953 public float getLineSpacing() {
954 return myLineSpacing;
957 public void setEditorFontSize(int fontSize) {
958 myFontSize = fontSize;
959 initFonts();
962 public void setLineSpacing(float lineSpacing) {
963 myLineSpacing = lineSpacing;
966 public void setEditorFontName(String fontName) {
967 myFontName = fontName;
968 initFonts();
971 public Object clone() {
972 return null;
975 public EditorColorsScheme getOriginalScheme() {
976 return myParentScheme;
979 public void setIsNew() {
980 myIsNew = true;
983 public boolean isNew() {
984 return myIsNew;
988 public String getId() {
989 return getHelpTopic();
992 @Nullable
993 public Runnable enableSearch(final String option) {
994 return null;
997 @Nullable
998 public SearchableConfigurable findSubConfigurable(String id) {
999 for (SearchableConfigurable configurable : mySubPanels.values()) {
1000 if (Comparing.strEqual(configurable.getId(), id)){
1001 return configurable;
1004 return null;
1007 private class InnerSearchableConfigurable implements SearchableConfigurable, OptionsContainingConfigurable {
1008 private final NewColorAndFontPanel mySubPanel;
1009 private boolean mySubInitInvoked = false;
1011 public InnerSearchableConfigurable(final NewColorAndFontPanel subPanel) {
1012 mySubPanel = subPanel;
1015 @Nls
1016 public String getDisplayName() {
1017 return mySubPanel.getDisplayName();
1020 public Icon getIcon() {
1021 return null;
1024 public String getHelpTopic() {
1025 return null;
1028 public JComponent createComponent() {
1029 return mySubPanel.getPanel();
1032 public boolean isModified() {
1033 for (MyColorScheme scheme : mySchemes.values()) {
1034 if (mySubPanel.containsFontOptions()) {
1035 if (scheme.isFontModified()) {
1036 myRevertChangesCompleted = false;
1037 return true;
1040 else {
1041 for (EditorSchemeAttributeDescriptor descriptor : scheme.getDescriptors()) {
1042 if (mySubPanel.contains(descriptor) && descriptor.isModified()) {
1043 myRevertChangesCompleted = false;
1044 return true;
1051 return false;
1055 public void apply() throws ConfigurationException {
1056 ColorAndFontOptions.this.apply();
1059 public void reset() {
1060 if (!mySubInitInvoked) {
1061 if (!myInitResetCompleted) {
1062 ColorAndFontOptions.this.resetFromChild();
1064 mySubInitInvoked = true;
1066 else {
1067 ColorAndFontOptions.this.revertChanges();
1071 public void disposeUIResources() {
1072 ColorAndFontOptions.this.disposeUIResources();
1075 public String getId() {
1076 return ColorAndFontOptions.this.getId() + "." + getDisplayName();
1079 public Runnable enableSearch(final String option) {
1080 return mySubPanel.showOption(option);
1083 public Set<String> processListOptions() {
1084 return mySubPanel.processListOptions();