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
.application
.options
.colors
;
19 import com
.intellij
.application
.options
.OptionsContainingConfigurable
;
20 import com
.intellij
.application
.options
.editor
.EditorOptionsProvider
;
21 import com
.intellij
.codeInsight
.daemon
.DaemonCodeAnalyzer
;
22 import com
.intellij
.codeInsight
.daemon
.impl
.DaemonCodeAnalyzerImpl
;
23 import com
.intellij
.openapi
.Disposable
;
24 import com
.intellij
.openapi
.application
.ApplicationBundle
;
25 import com
.intellij
.openapi
.diff
.impl
.settings
.DiffOptionsPanel
;
26 import com
.intellij
.openapi
.diff
.impl
.settings
.DiffPreviewPanel
;
27 import com
.intellij
.openapi
.editor
.EditorFactory
;
28 import com
.intellij
.openapi
.editor
.colors
.ColorKey
;
29 import com
.intellij
.openapi
.editor
.colors
.EditorColorsManager
;
30 import com
.intellij
.openapi
.editor
.colors
.EditorColorsScheme
;
31 import com
.intellij
.openapi
.editor
.colors
.TextAttributesKey
;
32 import com
.intellij
.openapi
.editor
.colors
.ex
.DefaultColorSchemesManager
;
33 import com
.intellij
.openapi
.editor
.colors
.impl
.DefaultColorsScheme
;
34 import com
.intellij
.openapi
.editor
.colors
.impl
.EditorColorsSchemeImpl
;
35 import com
.intellij
.openapi
.editor
.colors
.impl
.ReadOnlyColorsScheme
;
36 import com
.intellij
.openapi
.editor
.markup
.EffectType
;
37 import com
.intellij
.openapi
.editor
.markup
.TextAttributes
;
38 import com
.intellij
.openapi
.options
.Configurable
;
39 import com
.intellij
.openapi
.options
.ConfigurationException
;
40 import com
.intellij
.openapi
.options
.ExternalizableScheme
;
41 import com
.intellij
.openapi
.options
.SearchableConfigurable
;
42 import com
.intellij
.openapi
.options
.colors
.AttributesDescriptor
;
43 import com
.intellij
.openapi
.options
.colors
.ColorDescriptor
;
44 import com
.intellij
.openapi
.options
.colors
.ColorSettingsPage
;
45 import com
.intellij
.openapi
.options
.colors
.ColorSettingsPages
;
46 import com
.intellij
.openapi
.project
.Project
;
47 import com
.intellij
.openapi
.project
.ProjectManager
;
48 import com
.intellij
.openapi
.util
.Comparing
;
49 import com
.intellij
.openapi
.util
.Disposer
;
50 import com
.intellij
.openapi
.util
.IconLoader
;
51 import com
.intellij
.openapi
.util
.Pair
;
52 import com
.intellij
.openapi
.vcs
.FileStatus
;
53 import com
.intellij
.openapi
.vcs
.FileStatusFactory
;
54 import com
.intellij
.openapi
.vcs
.FileStatusManager
;
55 import com
.intellij
.psi
.search
.scope
.packageSet
.NamedScope
;
56 import com
.intellij
.psi
.search
.scope
.packageSet
.NamedScopesHolder
;
57 import com
.intellij
.psi
.search
.scope
.packageSet
.PackageSet
;
58 import com
.intellij
.util
.ArrayUtil
;
59 import com
.intellij
.util
.containers
.HashMap
;
60 import gnu
.trove
.THashSet
;
61 import gnu
.trove
.TObjectHashingStrategy
;
62 import org
.jetbrains
.annotations
.Nls
;
63 import org
.jetbrains
.annotations
.NotNull
;
64 import org
.jetbrains
.annotations
.Nullable
;
69 import java
.util
.List
;
71 public class ColorAndFontOptions
extends SearchableConfigurable
.Parent
.Abstract
implements EditorOptionsProvider
{
72 private HashMap
<String
,MyColorScheme
> mySchemes
;
73 private MyColorScheme mySelectedScheme
;
74 public static final String DIFF_GROUP
= ApplicationBundle
.message("title.diff");
75 public static final String FILE_STATUS_GROUP
= ApplicationBundle
.message("title.file.status");
76 public static final String SCOPES_GROUP
= ApplicationBundle
.message("title.scope.based");
78 private boolean mySomeSchemesDeleted
= false;
79 private Map
<ColorAndFontPanelFactory
, InnerSearchableConfigurable
> mySubPanelFactories
;
81 private SchemesPanel myRootSchemesPanel
;
83 private boolean myInitResetCompleted
= false;
84 private boolean myInitResetInvoked
= false;
86 private boolean myRevertChangesCompleted
= false;
88 private boolean myApplyCompleted
= false;
89 private boolean myDisposeCompleted
= false;
90 private final Disposable myDisposable
= Disposer
.newDisposable();
92 public boolean isModified() {
93 boolean listModified
= isSchemeListModified();
94 boolean schemeModified
= isSomeSchemeModified();
96 if (listModified
|| schemeModified
) {
97 myApplyCompleted
= false;
103 private boolean isSchemeListModified(){
104 if (mySomeSchemesDeleted
) return true;
106 if (!mySelectedScheme
.getName().equals(EditorColorsManager
.getInstance().getGlobalScheme().getName())) return true;
108 for (MyColorScheme scheme
: mySchemes
.values()) {
109 if (scheme
.isNew()) return true;
115 private boolean isSomeSchemeModified() {
116 for (MyColorScheme scheme
: mySchemes
.values()) {
117 if (scheme
.isModified()) return true;
122 public EditorColorsScheme
selectScheme(@NotNull String name
) {
123 mySelectedScheme
= getScheme(name
);
124 return mySelectedScheme
;
127 private MyColorScheme
getScheme(String name
) {
128 return mySchemes
.get(name
);
131 public EditorColorsScheme
getSelectedScheme() {
132 return mySelectedScheme
;
135 public EditorColorsScheme
getOriginalSelectedScheme() {
136 return mySelectedScheme
== null ?
null : mySelectedScheme
.getOriginalScheme();
139 public EditorSchemeAttributeDescriptor
[] getCurrentDescriptions() {
140 return mySelectedScheme
.getDescriptors();
143 public static boolean isReadOnly(final EditorColorsScheme scheme
) {
144 return ((MyColorScheme
)scheme
).isReadOnly();
147 public String
[] getSchemeNames() {
148 ArrayList
<MyColorScheme
> schemes
= new ArrayList
<MyColorScheme
>(mySchemes
.values());
149 Collections
.sort(schemes
, new Comparator
<MyColorScheme
>() {
150 public int compare(MyColorScheme o1
, MyColorScheme o2
) {
151 if (isReadOnly(o1
) && !isReadOnly(o2
)) return -1;
152 if (!isReadOnly(o1
) && isReadOnly(o2
)) return 1;
154 return o1
.getName().compareToIgnoreCase(o2
.getName());
158 ArrayList
<String
> names
= new ArrayList
<String
>(schemes
.size());
159 for (MyColorScheme scheme
: schemes
) {
160 names
.add(scheme
.getName());
163 return ArrayUtil
.toStringArray(names
);
166 public Collection
<EditorColorsScheme
> getSchemes() {
167 return new ArrayList
<EditorColorsScheme
>(mySchemes
.values());
170 public void saveSchemeAs(String name
) {
171 MyColorScheme scheme
= mySelectedScheme
;
172 if (scheme
== null) return;
174 EditorColorsScheme clone
= (EditorColorsScheme
)scheme
.getOriginalScheme().clone();
179 MyColorScheme newScheme
= new MyColorScheme(clone
);
180 initScheme(newScheme
);
182 newScheme
.setIsNew();
184 mySchemes
.put(name
, newScheme
);
185 selectScheme(newScheme
.getName());
186 resetSchemesCombo(null);
189 public void addImportedScheme(final EditorColorsScheme imported
) {
190 MyColorScheme newScheme
= new MyColorScheme(imported
);
191 initScheme(newScheme
);
193 mySchemes
.put(imported
.getName(), newScheme
);
194 selectScheme(newScheme
.getName());
195 resetSchemesCombo(null);
198 public void removeScheme(String name
) {
199 if (mySelectedScheme
.getName().equals(name
)) {
200 //noinspection HardCodedStringLiteral
201 selectScheme("Default");
204 boolean deletedNewlyCreated
= false;
206 MyColorScheme toDelete
= mySchemes
.get(name
);
208 if (toDelete
!= null) {
209 deletedNewlyCreated
= toDelete
.isNew();
212 mySchemes
.remove(name
);
213 resetSchemesCombo(null);
214 mySomeSchemesDeleted
= mySomeSchemesDeleted
|| !deletedNewlyCreated
;
217 public void apply() throws ConfigurationException
{
218 if (!myApplyCompleted
) {
220 EditorColorsManager myColorsManager
= EditorColorsManager
.getInstance();
222 myColorsManager
.removeAllSchemes();
223 for (MyColorScheme scheme
: mySchemes
.values()) {
224 if (!scheme
.isDefault()) {
226 myColorsManager
.addColorsScheme(scheme
.getOriginalScheme());
230 EditorColorsScheme originalScheme
= mySelectedScheme
.getOriginalScheme();
231 myColorsManager
.setGlobalScheme(originalScheme
);
233 applyChangesToEditors();
238 myApplyCompleted
= true;
248 // resetSchemesCombo();
253 private static void applyChangesToEditors() {
254 EditorFactory
.getInstance().refreshAllEditors();
256 Project
[] openProjects
= ProjectManager
.getInstance().getOpenProjects();
257 for (Project openProject
: openProjects
) {
258 FileStatusManager
.getInstance(openProject
).fileStatusesChanged();
259 DaemonCodeAnalyzer
.getInstance(openProject
).restart();
263 private boolean myIsReset
= false;
265 private void resetSchemesCombo(Object source
) {
268 myRootSchemesPanel
.resetSchemesCombo(source
);
269 if (mySubPanelFactories
!= null) {
270 for (NewColorAndFontPanel subPartialConfigurable
: getPanels()) {
271 subPartialConfigurable
.reset(source
);
281 public JComponent
createComponent() {
282 if (myRootSchemesPanel
== null) {
283 ensureSchemesPanel();
285 return myRootSchemesPanel
;
289 public boolean hasOwnContent() {
293 protected Configurable
[] buildConfigurables() {
294 myDisposeCompleted
= false;
297 List
<ColorAndFontPanelFactory
> panelFactories
= createPanelFactories();
299 List
<Configurable
> result
= new ArrayList
<Configurable
>();
300 mySubPanelFactories
= new LinkedHashMap
<ColorAndFontPanelFactory
, InnerSearchableConfigurable
>(panelFactories
.size());
301 for (ColorAndFontPanelFactory panelFactory
: panelFactories
) {
302 mySubPanelFactories
.put(panelFactory
, new InnerSearchableConfigurable(panelFactory
));
305 result
.addAll(new ArrayList
<SearchableConfigurable
>(mySubPanelFactories
.values()));
307 return result
.toArray(new Configurable
[result
.size()]);
310 private Set
<NewColorAndFontPanel
> getPanels() {
311 Set
<NewColorAndFontPanel
> result
= new HashSet
<NewColorAndFontPanel
>();
312 for (InnerSearchableConfigurable configurable
: mySubPanelFactories
.values()) {
313 NewColorAndFontPanel panel
= configurable
.getSubPanelIfInitialized();
321 private List
<ColorAndFontPanelFactory
> createPanelFactories() {
322 ArrayList
<ColorAndFontPanelFactory
> result
= new ArrayList
<ColorAndFontPanelFactory
>();
323 result
.add(new FontConfigurableFactory());
325 ColorSettingsPage
[] pages
= ColorSettingsPages
.getInstance().getRegisteredPages();
326 for (final ColorSettingsPage page
: pages
) {
327 result
.add(new ColorAndFontPanelFactory() {
328 public NewColorAndFontPanel
createPanel(ColorAndFontOptions options
) {
329 final SimpleEditorPreview preview
= new SimpleEditorPreview(options
, page
);
330 return NewColorAndFontPanel
.create(preview
, page
.getDisplayName(), options
, null, page
);
333 public String
getPanelDisplayName() {
334 return page
.getDisplayName();
338 result
.add(new DiffColorsPageFactory());
339 result
.add(new FileStatusColorsPageFactory());
340 result
.add(new ScopeColorsPageFactory());
345 private static class FontConfigurableFactory
implements ColorAndFontPanelFactory
{
346 public NewColorAndFontPanel
createPanel(ColorAndFontOptions options
) {
347 return new NewColorAndFontPanel(new SchemesPanel(options
), new FontOptions(options
), new FontEditorPreview(options
), "Font", null, null){
349 public boolean containsFontOptions() {
355 public String
getPanelDisplayName() {
360 private class DiffColorsPageFactory
implements ColorAndFontPanelFactory
{
361 public NewColorAndFontPanel
createPanel(ColorAndFontOptions options
) {
362 final DiffPreviewPanel diffPreviewPanel
= new DiffPreviewPanel(myDisposable
);
363 diffPreviewPanel
.setMergeRequest(null);
364 final DiffOptionsPanel optionsPanel
= new DiffOptionsPanel(options
);
366 SchemesPanel schemesPanel
= new SchemesPanel(options
);
368 schemesPanel
.addListener(new ColorAndFontSettingsListener
.Abstract(){
370 public void schemeChanged(final Object source
) {
371 diffPreviewPanel
.setColorScheme(getSelectedScheme());
372 optionsPanel
.updateOptionsList();
373 diffPreviewPanel
.updateView();
377 return new NewColorAndFontPanel(schemesPanel
, optionsPanel
, diffPreviewPanel
, DIFF_GROUP
, null, null);
380 public String
getPanelDisplayName() {
385 private void initAll() {
386 EditorColorsManager colorsManager
= EditorColorsManager
.getInstance();
387 EditorColorsScheme
[] allSchemes
= colorsManager
.getAllSchemes();
389 mySchemes
= new HashMap
<String
, MyColorScheme
>();
390 for (EditorColorsScheme allScheme
: allSchemes
) {
391 MyColorScheme schemeDelegate
= new MyColorScheme(allScheme
);
392 initScheme(schemeDelegate
);
393 mySchemes
.put(schemeDelegate
.getName(), schemeDelegate
);
396 mySelectedScheme
= mySchemes
.get(EditorColorsManager
.getInstance().getGlobalScheme().getName());
397 assert mySelectedScheme
!= null : EditorColorsManager
.getInstance().getGlobalScheme().getName() + "; myschemes=" + mySchemes
;
400 private static void initScheme(MyColorScheme scheme
) {
401 ArrayList
<EditorSchemeAttributeDescriptor
> descriptions
= new ArrayList
<EditorSchemeAttributeDescriptor
>();
402 initPluggedDescriptions(descriptions
, scheme
);
403 initDiffDescriptors(descriptions
, scheme
);
404 initFileStatusDescriptors(descriptions
, scheme
);
405 initScopesDescriptors(descriptions
, scheme
);
407 scheme
.setDescriptors(descriptions
.toArray(new EditorSchemeAttributeDescriptor
[descriptions
.size()]));
410 private static void initPluggedDescriptions(ArrayList
<EditorSchemeAttributeDescriptor
> descriptions
, MyColorScheme scheme
) {
411 ColorSettingsPage
[] pages
= ColorSettingsPages
.getInstance().getRegisteredPages();
412 for (ColorSettingsPage page
: pages
) {
413 initDescriptions(page
, descriptions
, scheme
);
417 private static void initDescriptions(ColorSettingsPage page
,
418 ArrayList
<EditorSchemeAttributeDescriptor
> descriptions
,
419 MyColorScheme scheme
) {
420 String group
= page
.getDisplayName();
421 AttributesDescriptor
[] attributeDescriptors
= page
.getAttributeDescriptors();
422 for (AttributesDescriptor descriptor
: attributeDescriptors
) {
423 addSchemedDescription(descriptions
, descriptor
.getDisplayName(), group
, descriptor
.getKey(), scheme
, null, null);
426 ColorDescriptor
[] colorDescriptors
= page
.getColorDescriptors();
427 for (ColorDescriptor descriptor
: colorDescriptors
) {
428 ColorKey back
= descriptor
.getKind() == ColorDescriptor
.Kind
.BACKGROUND ? descriptor
.getKey() : null;
429 ColorKey fore
= descriptor
.getKind() == ColorDescriptor
.Kind
.FOREGROUND ? descriptor
.getKey() : null;
430 addEditorSettingDescription(descriptions
, descriptor
.getDisplayName(), group
, back
, fore
, scheme
);
434 private static void initDiffDescriptors(ArrayList
<EditorSchemeAttributeDescriptor
> descriptions
, MyColorScheme scheme
) {
435 DiffOptionsPanel
.addSchemeDescriptions(descriptions
, scheme
);
438 private static void initFileStatusDescriptors(ArrayList
<EditorSchemeAttributeDescriptor
> descriptions
, MyColorScheme scheme
) {
440 FileStatus
[] statuses
= FileStatusFactory
.SERVICE
.getInstance().getAllFileStatuses();
442 for (FileStatus fileStatus
: statuses
) {
443 addEditorSettingDescription(descriptions
,
444 fileStatus
.getText(),
447 fileStatus
.getColorKey(),
452 private static void initScopesDescriptors(ArrayList
<EditorSchemeAttributeDescriptor
> descriptions
, MyColorScheme scheme
) {
453 Set
<Pair
<NamedScope
,NamedScopesHolder
>> namedScopes
= new THashSet
<Pair
<NamedScope
,NamedScopesHolder
>>(new TObjectHashingStrategy
<Pair
<NamedScope
,NamedScopesHolder
>>() {
454 public int computeHashCode(final Pair
<NamedScope
, NamedScopesHolder
> object
) {
455 return object
.getFirst().getName().hashCode();
458 public boolean equals(final Pair
<NamedScope
, NamedScopesHolder
> o1
, final Pair
<NamedScope
, NamedScopesHolder
> o2
) {
459 return o1
.getFirst().getName().equals(o2
.getFirst().getName());
462 Project
[] projects
= ProjectManager
.getInstance().getOpenProjects();
463 for (Project project
: projects
) {
464 DaemonCodeAnalyzerImpl codeAnalyzer
= (DaemonCodeAnalyzerImpl
)DaemonCodeAnalyzer
.getInstance(project
);
465 List
<Pair
<NamedScope
,NamedScopesHolder
>> cachedScopes
= codeAnalyzer
.getScopeBasedHighlightingCachedScopes();
466 namedScopes
.addAll(cachedScopes
);
469 List
<Pair
<NamedScope
, NamedScopesHolder
>> list
= new ArrayList
<Pair
<NamedScope
, NamedScopesHolder
>>(namedScopes
);
471 Collections
.sort(list
, new Comparator
<Pair
<NamedScope
,NamedScopesHolder
>>() {
472 public int compare(final Pair
<NamedScope
,NamedScopesHolder
> o1
, final Pair
<NamedScope
,NamedScopesHolder
> o2
) {
473 return o1
.getFirst().getName().compareToIgnoreCase(o2
.getFirst().getName());
476 for (Pair
<NamedScope
,NamedScopesHolder
> pair
: list
) {
477 NamedScope namedScope
= pair
.getFirst();
478 String name
= namedScope
.getName();
479 TextAttributesKey textAttributesKey
= getScopeTextAttributeKey(name
);
480 if (scheme
.getAttributes(textAttributesKey
) == null) {
481 scheme
.setAttributes(textAttributesKey
, new TextAttributes());
483 NamedScopesHolder holder
= pair
.getSecond();
485 PackageSet value
= namedScope
.getValue();
486 String toolTip
= holder
.getDisplayName() + (value
==null ?
"" : ": "+ value
.getText());
487 addSchemedDescription(descriptions
,
491 scheme
, holder
.getIcon(), toolTip
);
495 public static TextAttributesKey
getScopeTextAttributeKey(final String scope
) {
496 return TextAttributesKey
.find("SCOPE_KEY_" + scope
);
499 private static void addEditorSettingDescription(ArrayList
<EditorSchemeAttributeDescriptor
> array
,
502 ColorKey backgroundKey
,
503 ColorKey foregroundKey
,
504 EditorColorsScheme scheme
) {
506 if (foregroundKey
!= null) {
507 type
= foregroundKey
.getExternalName();
510 if (backgroundKey
!= null) {
511 type
= backgroundKey
.getExternalName();
514 ColorAndFontDescription descr
= new EditorSettingColorDescription(name
, group
, backgroundKey
, foregroundKey
, type
, scheme
);
518 private static void addSchemedDescription(ArrayList
<EditorSchemeAttributeDescriptor
> array
, String name
, String group
, TextAttributesKey key
,
519 EditorColorsScheme scheme
,
522 ColorAndFontDescription descr
= new SchemeTextAttributesDescription(name
, group
, key
, scheme
, icon
, toolTip
);
526 public String
getDisplayName() {
527 return ApplicationBundle
.message("title.colors.and.fonts");
530 public Icon
getIcon() {
531 return IconLoader
.getIcon("/general/configurableColorsAndFonts.png");
534 private void revertChanges(){
535 if (isSchemeListModified() || isSomeSchemeModified()) {
536 myRevertChangesCompleted
= false;
539 if (!myRevertChangesCompleted
) {
540 ensureSchemesPanel();
547 myRevertChangesCompleted
= true;
553 private void resetImpl() {
554 mySomeSchemesDeleted
= false;
556 resetSchemesCombo(null);
559 public synchronized void reset() {
560 if (!myInitResetInvoked
) {
563 if (!myInitResetCompleted
) {
564 ensureSchemesPanel();
570 myInitResetCompleted
= true;
575 myInitResetInvoked
= true;
585 public synchronized void resetFromChild() {
586 if (!myInitResetCompleted
) {
587 ensureSchemesPanel();
594 myInitResetCompleted
= true;
600 private void ensureSchemesPanel() {
601 if (myRootSchemesPanel
== null) {
602 myRootSchemesPanel
= new SchemesPanel(this);
604 myRootSchemesPanel
.addListener(new ColorAndFontSettingsListener
.Abstract(){
606 public void schemeChanged(final Object source
) {
608 resetSchemesCombo(source
);
616 public void disposeUIResources() {
618 if (!myDisposeCompleted
) {
620 super.disposeUIResources();
621 Disposer
.dispose(myDisposable
);
622 if (myRootSchemesPanel
!= null) {
623 myRootSchemesPanel
.disposeUIResources();
627 myDisposeCompleted
= true;
632 mySubPanelFactories
= null;
634 myInitResetCompleted
= false;
635 myInitResetInvoked
= false;
636 myRevertChangesCompleted
= false;
638 myApplyCompleted
= false;
639 myRootSchemesPanel
= null;
643 public boolean currentSchemeIsReadOnly() {
644 return isReadOnly(mySelectedScheme
);
647 public boolean currentSchemeIsShared() {
648 return ColorSettingsUtil
.isSharedScheme(mySelectedScheme
);
652 private static class SchemeTextAttributesDescription
extends TextAttributesDescription
{
653 private final TextAttributes myAttributesToApply
;
654 private final TextAttributesKey key
;
656 private SchemeTextAttributesDescription(String name
, String group
, TextAttributesKey key
, EditorColorsScheme scheme
, Icon icon
,
659 scheme
.getAttributes(key
) == null
660 ?
new TextAttributes()
661 : scheme
.getAttributes(key
).clone(),
662 key
, scheme
, icon
, toolTip
);
664 myAttributesToApply
= scheme
.getAttributes(key
);
668 public void apply(EditorColorsScheme scheme
) {
669 if (scheme
== null) scheme
= getScheme();
670 if (myAttributesToApply
!= null) {
671 scheme
.setAttributes(key
, getTextAttributes());
675 public boolean isModified() {
676 return !Comparing
.equal(myAttributesToApply
, getTextAttributes());
679 public boolean isErrorStripeEnabled() {
684 private static class GetSetColor
{
685 private final ColorKey myKey
;
686 private final EditorColorsScheme myScheme
;
687 private boolean isModified
= false;
688 private Color myColor
;
690 private GetSetColor(ColorKey key
, EditorColorsScheme scheme
) {
693 myColor
= myScheme
.getColor(myKey
);
696 public Color
getColor() {
700 public void setColor(Color col
) {
701 if (getColor() == null || !getColor().equals(col
)) {
707 public void apply(EditorColorsScheme scheme
) {
708 if (scheme
== null) scheme
= myScheme
;
709 scheme
.setColor(myKey
, myColor
);
712 public boolean isModified() {
717 private static class EditorSettingColorDescription
extends ColorAndFontDescription
{
718 private GetSetColor myGetSetForeground
;
719 private GetSetColor myGetSetBackground
;
721 private EditorSettingColorDescription(String name
,
723 ColorKey backgroundKey
,
724 ColorKey foregroundKey
,
726 EditorColorsScheme scheme
) {
727 super(name
, group
, type
, scheme
, null, null);
728 if (backgroundKey
!= null) {
729 myGetSetBackground
= new GetSetColor(backgroundKey
, scheme
);
731 if (foregroundKey
!= null) {
732 myGetSetForeground
= new GetSetColor(foregroundKey
, scheme
);
737 public int getFontType() {
741 public void setFontType(int type
) {
744 public Color
getExternalEffectColor() {
748 public void setExternalEffectColor(Color color
) {
751 public void setExternalEffectType(EffectType type
) {
754 public EffectType
getExternalEffectType() {
755 return EffectType
.LINE_UNDERSCORE
;
758 public Color
getExternalForeground() {
759 if (myGetSetForeground
== null) {
762 return myGetSetForeground
.getColor();
765 public void setExternalForeground(Color col
) {
766 if (myGetSetForeground
== null) {
769 myGetSetForeground
.setColor(col
);
772 public Color
getExternalBackground() {
773 if (myGetSetBackground
== null) {
776 return myGetSetBackground
.getColor();
779 public void setExternalBackground(Color col
) {
780 if (myGetSetBackground
== null) {
783 myGetSetBackground
.setColor(col
);
786 public Color
getExternalErrorStripe() {
790 public void setExternalErrorStripe(Color col
) {
793 public boolean isFontEnabled() {
797 public boolean isForegroundEnabled() {
798 return myGetSetForeground
!= null;
801 public boolean isBackgroundEnabled() {
802 return myGetSetBackground
!= null;
805 public boolean isEffectsColorEnabled() {
809 public boolean isModified() {
810 return myGetSetBackground
!= null && myGetSetBackground
.isModified()
811 || myGetSetForeground
!= null && myGetSetForeground
.isModified();
814 public void apply(EditorColorsScheme scheme
) {
815 if (myGetSetBackground
!= null) {
816 myGetSetBackground
.apply(scheme
);
818 if (myGetSetForeground
!= null) {
819 myGetSetForeground
.apply(scheme
);
824 public String
getHelpTopic() {
825 return "reference.settingsdialog.IDE.editor.colors";
828 private static class MyColorScheme
extends EditorColorsSchemeImpl
{
829 private int myFontSize
;
830 private float myLineSpacing
;
831 private String myFontName
;
832 private EditorSchemeAttributeDescriptor
[] myDescriptors
;
833 private String myName
;
834 private boolean myIsNew
= false;
836 private MyColorScheme(EditorColorsScheme parenScheme
) {
837 super(parenScheme
, DefaultColorSchemesManager
.getInstance());
838 myFontSize
= parenScheme
.getEditorFontSize();
839 myLineSpacing
= parenScheme
.getLineSpacing();
840 myFontName
= parenScheme
.getEditorFontName();
841 myName
= parenScheme
.getName();
842 if (parenScheme
instanceof ExternalizableScheme
) {
843 getExternalInfo().copy(((ExternalizableScheme
)parenScheme
).getExternalInfo());
848 public String
getName() {
852 public void setName(String name
) {
856 public void setDescriptors(EditorSchemeAttributeDescriptor
[] descriptors
) {
857 myDescriptors
= descriptors
;
860 public EditorSchemeAttributeDescriptor
[] getDescriptors() {
861 return myDescriptors
;
864 public boolean isDefault() {
865 return myParentScheme
instanceof DefaultColorsScheme
;
868 public boolean isReadOnly() {
869 return myParentScheme
instanceof ReadOnlyColorsScheme
;
872 public boolean isModified() {
873 if (isFontModified()) return true;
875 for (EditorSchemeAttributeDescriptor descriptor
: myDescriptors
) {
876 if (descriptor
.isModified()) {
884 private boolean isFontModified() {
885 if (myFontSize
!= myParentScheme
.getEditorFontSize()) return true;
886 if (myLineSpacing
!= myParentScheme
.getLineSpacing()) return true;
887 if (!myFontName
.equals(myParentScheme
.getEditorFontName())) return true;
891 public void apply() {
892 apply(myParentScheme
);
895 public void apply(EditorColorsScheme scheme
) {
896 scheme
.setEditorFontSize(myFontSize
);
897 scheme
.setEditorFontName(myFontName
);
898 scheme
.setLineSpacing(myLineSpacing
);
900 for (EditorSchemeAttributeDescriptor descriptor
: myDescriptors
) {
901 descriptor
.apply(scheme
);
905 public String
getEditorFontName() {
909 public int getEditorFontSize() {
913 public float getLineSpacing() {
914 return myLineSpacing
;
917 public void setEditorFontSize(int fontSize
) {
918 myFontSize
= fontSize
;
922 public void setLineSpacing(float lineSpacing
) {
923 myLineSpacing
= lineSpacing
;
926 public void setEditorFontName(String fontName
) {
927 myFontName
= fontName
;
931 public Object
clone() {
935 public EditorColorsScheme
getOriginalScheme() {
936 return myParentScheme
;
939 public void setIsNew() {
943 public boolean isNew() {
948 public String
getId() {
949 return getHelpTopic();
953 public Runnable
enableSearch(final String option
) {
958 public InnerSearchableConfigurable
findSubConfigurable(final Class pageClass
) {
959 if (mySubPanelFactories
== null) {
960 buildConfigurables();
962 for (Map
.Entry
<ColorAndFontPanelFactory
, InnerSearchableConfigurable
> entry
: mySubPanelFactories
.entrySet()) {
963 if (pageClass
.isInstance(entry
.getValue().createPanel().getSettingsPage())) {
964 return entry
.getValue();
971 public NewColorAndFontPanel
findPage(String pageName
) {
972 if (mySubPanelFactories
== null) {
973 buildConfigurables();
975 for (InnerSearchableConfigurable configurable
: mySubPanelFactories
.values()) {
976 if (configurable
.getDisplayName().equals(pageName
)) {
977 return configurable
.createPanel();
983 private class InnerSearchableConfigurable
implements SearchableConfigurable
, OptionsContainingConfigurable
, NoScroll
{
984 private NewColorAndFontPanel mySubPanel
;
985 private boolean mySubInitInvoked
= false;
986 private final ColorAndFontPanelFactory myFactory
;
988 private InnerSearchableConfigurable(final ColorAndFontPanelFactory factory
) {
993 public String
getDisplayName() {
994 return myFactory
.getPanelDisplayName();
997 public NewColorAndFontPanel
getSubPanelIfInitialized() {
1001 private NewColorAndFontPanel
createPanel() {
1002 if (mySubPanel
== null) {
1003 mySubPanel
= myFactory
.createPanel(ColorAndFontOptions
.this);
1004 mySubPanel
.reset(this);
1005 mySubPanel
.addSchemesListener(new ColorAndFontSettingsListener
.Abstract(){
1006 public void schemeChanged(final Object source
) {
1008 resetSchemesCombo(source
);
1013 mySubPanel
.addDescriptionListener(new ColorAndFontSettingsListener
.Abstract(){
1015 public void fontChanged() {
1016 for (NewColorAndFontPanel panel
: getPanels()) {
1017 panel
.updatePreview();
1025 public Icon
getIcon() {
1029 public String
getHelpTopic() {
1033 public JComponent
createComponent() {
1034 return createPanel().getPanel();
1037 public boolean isModified() {
1039 for (MyColorScheme scheme
: mySchemes
.values()) {
1040 if (mySubPanel
.containsFontOptions()) {
1041 if (scheme
.isFontModified()) {
1042 myRevertChangesCompleted
= false;
1047 for (EditorSchemeAttributeDescriptor descriptor
: scheme
.getDescriptors()) {
1048 if (mySubPanel
.contains(descriptor
) && descriptor
.isModified()) {
1049 myRevertChangesCompleted
= false;
1061 public void apply() throws ConfigurationException
{
1062 ColorAndFontOptions
.this.apply();
1065 public void reset() {
1066 if (!mySubInitInvoked
) {
1067 if (!myInitResetCompleted
) {
1070 mySubInitInvoked
= true;
1077 public void disposeUIResources() {
1078 if (mySubPanel
!= null) {
1079 mySubPanel
.disposeUIResources();
1083 public String
getId() {
1084 return ColorAndFontOptions
.this.getId() + "." + getDisplayName();
1087 public Runnable
enableSearch(final String option
) {
1088 return createPanel().showOption(option
);
1091 public Set
<String
> processListOptions() {
1092 return createPanel().processListOptions();