1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include <svtools/colorcfg.hxx>
25 #include <com/sun/star/uno/Any.hxx>
26 #include <com/sun/star/uno/Sequence.hxx>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <comphelper/lok.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <unotools/configitem.hxx>
31 #include <unotools/confignode.hxx>
32 #include <unotools/configmgr.hxx>
33 #include <unotools/configpaths.hxx>
34 #include <com/sun/star/uno/Sequence.h>
35 #include <svl/poolitem.hxx>
37 #include <vcl/window.hxx>
39 #include "itemholder2.hxx"
41 #include <vcl/svapp.hxx>
42 #include <vcl/event.hxx>
43 #include <vcl/settings.hxx>
44 #include <vcl/themecolors.hxx>
45 #include <officecfg/Office/UI.hxx>
46 #include <officecfg/Office/Common.hxx>
49 using namespace com::sun::star
;
51 const char g_sIsVisible
[] = "/IsVisible";
57 static sal_Int32 nColorRefCount_Impl
= 0;
60 std::mutex
& ColorMutex_Impl()
62 static std::mutex SINGLETON
;
67 ColorConfig_Impl
* ColorConfig::m_pImpl
= nullptr;
69 class ColorConfig_Impl
: public utl::ConfigItem
71 ColorConfigValue m_aConfigValues
[ColorConfigEntryCount
];
72 OUString m_sLoadedScheme
;
74 virtual void ImplCommit() override
;
77 explicit ColorConfig_Impl();
78 virtual ~ColorConfig_Impl() override
;
80 void Load(const OUString
& rScheme
);
81 void CommitCurrentSchemeName();
82 //changes the name of the current scheme but doesn't load it!
83 void SetCurrentSchemeName(const OUString
& rSchemeName
) {m_sLoadedScheme
= rSchemeName
;}
84 virtual void Notify( const uno::Sequence
<OUString
>& aPropertyNames
) override
;
86 const ColorConfigValue
& GetColorConfigValue(ColorConfigEntry eValue
) const
87 {return m_aConfigValues
[eValue
];}
88 void SetColorConfigValue(ColorConfigEntry eValue
,
89 const ColorConfigValue
& rValue
);
91 const OUString
& GetLoadedScheme() const {return m_sLoadedScheme
;}
93 uno::Sequence
< OUString
> GetSchemeNames();
95 void AddScheme(const OUString
& rNode
);
96 void RemoveScheme(const OUString
& rNode
);
97 using ConfigItem::SetModified
;
98 using ConfigItem::ClearModified
;
99 void SettingsChanged();
101 DECL_LINK( DataChangedEventListener
, VclSimpleEvent
&, void );
106 uno::Sequence
< OUString
> GetPropertyNames(std::u16string_view rScheme
)
108 struct ColorConfigEntryData_Impl
110 std::u16string_view cName
;
113 static const ColorConfigEntryData_Impl cNames
[] =
115 { std::u16string_view(u
"/DocColor") ,false },
116 { std::u16string_view(u
"/DocBoundaries") ,false },
117 { std::u16string_view(u
"/AppBackground") ,false },
118 { std::u16string_view(u
"/TableBoundaries") ,false },
119 { std::u16string_view(u
"/FontColor") ,false },
120 { std::u16string_view(u
"/Links") ,true },
121 { std::u16string_view(u
"/LinksVisited") ,true },
122 { std::u16string_view(u
"/Spell") ,false },
123 { std::u16string_view(u
"/Grammar") ,false },
124 { std::u16string_view(u
"/SmartTags") ,false },
125 { std::u16string_view(u
"/Shadow") , true },
126 { std::u16string_view(u
"/WriterTextGrid") ,false },
127 { std::u16string_view(u
"/WriterFieldShadings"),true },
128 { std::u16string_view(u
"/WriterIdxShadings") ,true },
129 { std::u16string_view(u
"/WriterDirectCursor") ,true },
130 { std::u16string_view(u
"/WriterScriptIndicator") ,false },
131 { std::u16string_view(u
"/WriterSectionBoundaries") ,false },
132 { std::u16string_view(u
"/WriterHeaderFooterMark") ,false },
133 { std::u16string_view(u
"/WriterPageBreaks") ,false },
134 { std::u16string_view(u
"/WriterNonPrintChars") ,false },
135 { std::u16string_view(u
"/HTMLSGML") ,false },
136 { std::u16string_view(u
"/HTMLComment") ,false },
137 { std::u16string_view(u
"/HTMLKeyword") ,false },
138 { std::u16string_view(u
"/HTMLUnknown") ,false },
139 { std::u16string_view(u
"/CalcGrid") ,false },
140 { std::u16string_view(u
"/CalcCellFocus") ,false },
141 { std::u16string_view(u
"/CalcPageBreak"), false },
142 { std::u16string_view(u
"/CalcPageBreakManual"), false },
143 { std::u16string_view(u
"/CalcPageBreakAutomatic"), false },
144 { std::u16string_view(u
"/CalcHiddenColRow"), true },
145 { std::u16string_view(u
"/CalcTextOverflow"), true },
146 { std::u16string_view(u
"/CalcComments"), false },
147 { std::u16string_view(u
"/CalcDetective") ,false },
148 { std::u16string_view(u
"/CalcDetectiveError") ,false },
149 { std::u16string_view(u
"/CalcReference") ,false },
150 { std::u16string_view(u
"/CalcNotesBackground") ,false },
151 { std::u16string_view(u
"/CalcValue") ,false },
152 { std::u16string_view(u
"/CalcFormula") ,false },
153 { std::u16string_view(u
"/CalcText") ,false },
154 { std::u16string_view(u
"/CalcProtectedBackground") ,false },
155 { std::u16string_view(u
"/DrawGrid") ,true },
156 { std::u16string_view(u
"/Author1"), false },
157 { std::u16string_view(u
"/Author2"), false },
158 { std::u16string_view(u
"/Author3"), false },
159 { std::u16string_view(u
"/Author4"), false },
160 { std::u16string_view(u
"/Author5"), false },
161 { std::u16string_view(u
"/Author6"), false },
162 { std::u16string_view(u
"/Author7"), false },
163 { std::u16string_view(u
"/Author8"), false },
164 { std::u16string_view(u
"/Author9"), false },
165 { std::u16string_view(u
"/BASICEditor"), false },
166 { std::u16string_view(u
"/BASICIdentifier"), false },
167 { std::u16string_view(u
"/BASICComment") , false },
168 { std::u16string_view(u
"/BASICNumber") , false },
169 { std::u16string_view(u
"/BASICString") , false },
170 { std::u16string_view(u
"/BASICOperator") , false },
171 { std::u16string_view(u
"/BASICKeyword") , false },
172 { std::u16string_view(u
"/BASICError"), false },
173 { std::u16string_view(u
"/SQLIdentifier"), false },
174 { std::u16string_view(u
"/SQLNumber"), false },
175 { std::u16string_view(u
"/SQLString"), false },
176 { std::u16string_view(u
"/SQLOperator"), false },
177 { std::u16string_view(u
"/SQLKeyword"), false },
178 { std::u16string_view(u
"/SQLParameter"), false },
179 { std::u16string_view(u
"/SQLComment"), false },
181 { std::u16string_view(u
"/WindowColor") ,false },
182 { std::u16string_view(u
"/WindowTextColor") ,false },
183 { std::u16string_view(u
"/BaseColor") ,false },
184 { std::u16string_view(u
"/ButtonColor") ,false },
185 { std::u16string_view(u
"/ButtonTextColor") ,false },
186 { std::u16string_view(u
"/AccentColor") ,false },
187 { std::u16string_view(u
"/DisabledColor") ,false },
188 { std::u16string_view(u
"/DisabledTextColor") ,false },
189 { std::u16string_view(u
"/ShadowColor") ,false },
190 { std::u16string_view(u
"/SeparatorColor") ,false },
191 { std::u16string_view(u
"/FaceColor") ,false },
192 { std::u16string_view(u
"/ActiveColor") ,false },
193 { std::u16string_view(u
"/ActiveTextColor") ,false },
194 { std::u16string_view(u
"/ActiveBorderColor") ,false },
195 { std::u16string_view(u
"/FieldColor") ,false },
196 { std::u16string_view(u
"/MenuBarColor") ,false },
197 { std::u16string_view(u
"/MenuBarTextColor") ,false },
198 { std::u16string_view(u
"/MenuBarHighlightColor") ,false },
199 { std::u16string_view(u
"/MenuBarHighlightTextColor") ,false },
200 { std::u16string_view(u
"/MenuColor") ,false },
201 { std::u16string_view(u
"/MenuTextColor") ,false },
202 { std::u16string_view(u
"/MenuHighlightColor") ,false },
203 { std::u16string_view(u
"/MenuHighlightTextColor") ,false },
204 { std::u16string_view(u
"/MenuBorderColor") ,false },
205 { std::u16string_view(u
"/InactiveColor") ,false },
206 { std::u16string_view(u
"/InactiveTextColor") ,false },
207 { std::u16string_view(u
"/InactiveBorderColor") ,false }
210 uno::Sequence
<OUString
> aNames(2 * ColorConfigEntryCount
);
211 OUString
* pNames
= aNames
.getArray();
213 OUString sBase
= "ColorSchemes/"
214 + utl::wrapConfigurationElementName(rScheme
);
215 for(sal_Int32 i
= 0; i
< ColorConfigEntryCount
; ++i
)
217 OUString sBaseName
= sBase
+ cNames
[i
].cName
;
218 pNames
[nIndex
++] = sBaseName
+ "/Color";
219 if(cNames
[i
].bCanBeVisible
)
221 pNames
[nIndex
++] = sBaseName
+ g_sIsVisible
;
224 aNames
.realloc(nIndex
);
230 ColorConfig_Impl::ColorConfig_Impl() :
231 ConfigItem(u
"Office.UI/ColorScheme"_ustr
)
233 //try to register on the root node - if possible
234 uno::Sequence
< OUString
> aNames(1);
235 EnableNotification( aNames
);
237 if (!comphelper::IsFuzzing())
240 ::Application::AddEventListener( LINK(this, ColorConfig_Impl
, DataChangedEventListener
) );
244 ColorConfig_Impl::~ColorConfig_Impl()
246 ::Application::RemoveEventListener( LINK(this, ColorConfig_Impl
, DataChangedEventListener
) );
249 void ColorConfig_Impl::Load(const OUString
& rScheme
)
251 OUString
sScheme(rScheme
);
252 if(sScheme
.isEmpty())
254 //detect current scheme name
255 uno::Sequence
< OUString
> aCurrent
{ u
"CurrentColorScheme"_ustr
};
256 uno::Sequence
< uno::Any
> aCurrentVal
= GetProperties( aCurrent
);
257 aCurrentVal
.getConstArray()[0] >>= sScheme
;
259 m_sLoadedScheme
= sScheme
;
261 // in cases like theme change/extension removal, use AUTOMATIC_COLOR_SCHEME as fallback.
262 if (!ThemeColors::IsAutomaticTheme(sScheme
))
264 uno::Sequence
<OUString
> aSchemes
= GetSchemeNames();
266 for (const OUString
& rSchemeName
: aSchemes
)
268 if (sScheme
== rSchemeName
)
276 sScheme
= AUTOMATIC_COLOR_SCHEME
;
279 uno::Sequence
< OUString
> aColorNames
= GetPropertyNames(sScheme
);
280 uno::Sequence
< uno::Any
> aColors
= GetProperties( aColorNames
);
281 const uno::Any
* pColors
= aColors
.getConstArray();
282 const OUString
* pColorNames
= aColorNames
.getConstArray();
283 sal_Int32 nIndex
= 0;
284 for(int i
= 0; i
< ColorConfigEntryCount
&& aColors
.getLength() > nIndex
; ++i
)
286 if(pColors
[nIndex
].hasValue())
289 pColors
[nIndex
] >>= nTmp
;
290 m_aConfigValues
[i
].nColor
= nTmp
;
293 m_aConfigValues
[i
].nColor
= COL_AUTO
;
295 if(nIndex
>= aColors
.getLength())
297 //test for visibility property
298 if(pColorNames
[nIndex
].endsWith(g_sIsVisible
))
299 m_aConfigValues
[i
].bIsVisible
= Any2Bool(pColors
[nIndex
++]);
303 void ColorConfig_Impl::Notify(const uno::Sequence
<OUString
>& rProperties
)
305 const OUString sOldLoadedScheme
= m_sLoadedScheme
;
307 ColorConfigValue aOldConfigValues
[ColorConfigEntryCount
];
308 std::copy( m_aConfigValues
, m_aConfigValues
+ ColorConfigEntryCount
, aOldConfigValues
);
310 // loading via notification always uses the default setting
313 const bool bNoColorSchemeChange
= sOldLoadedScheme
== m_sLoadedScheme
;
315 // If the name of the scheme hasn't changed, then there is no change to the
316 // global color scheme name, but Kit deliberately only changed the then
317 // current document when it last changed, so there are typically a mixture
318 // of documents with the original 'light' color scheme and the last changed
319 // color scheme 'dark'. Kit then tries to set the color scheme again to the
320 // last changed color scheme 'dark' to try and update a 'light' document
321 // that had opted out of the last change to 'dark'...
322 const bool bEmptyColorSchemeNotify
=
323 rProperties
.getLength() == 1
324 && rProperties
[0] == "CurrentColorScheme"
325 && bNoColorSchemeChange
;
327 // ...We can get into a similar situation with inverted backgrounds, for
328 // similar reasons, so even if we are only changing the current color scheme
329 // we need to make sure that something actually changed...
330 bool bNoConfigChange
= true;
331 for (int i
= 0; i
< ColorConfigEntryCount
; ++i
) {
332 if (aOldConfigValues
[i
] != m_aConfigValues
[i
]) {
333 bNoConfigChange
= false;
338 // ...and if something from a different color scheme changes, our config
339 // values wouldn't change anyway, so we need to make sure that if something
340 // changed it was this color scheme...
341 const OUString sCurrentSchemePropertyPrefix
= "ColorSchemes/org.openoffice.Office.UI:ColorScheme['" + m_sLoadedScheme
+ "']/";
342 bool bOnlyCurrentSchemeChanges
= true;
343 for (int i
= 0; i
< rProperties
.getLength(); ++i
) {
344 if (!rProperties
[i
].startsWith(sCurrentSchemePropertyPrefix
)) {
345 bOnlyCurrentSchemeChanges
= false;
350 bool bEmptyCurrentSchemeNotify
= bNoColorSchemeChange
&& bNoConfigChange
&& bOnlyCurrentSchemeChanges
;
352 // ...We can tag apparent null change attempts with
353 // 'OnlyCurrentDocumentColorScheme' to allow them to go through, but
354 // identify what that change is for, so the other color config listeners for
355 // whom it doesn't matter, can ignore it as an optimization.
356 const bool bOnlyCurrentDocumentColorScheme
= (bEmptyColorSchemeNotify
|| bEmptyCurrentSchemeNotify
) && comphelper::LibreOfficeKit::isActive();
357 NotifyListeners(bOnlyCurrentDocumentColorScheme
? ConfigurationHints::OnlyCurrentDocumentColorScheme
: ConfigurationHints::NONE
);
360 void ColorConfig_Impl::ImplCommit()
362 uno::Sequence
< OUString
> aColorNames
= GetPropertyNames(m_sLoadedScheme
);
363 uno::Sequence
< beans::PropertyValue
> aPropValues(aColorNames
.getLength());
364 beans::PropertyValue
* pPropValues
= aPropValues
.getArray();
365 const OUString
* pColorNames
= aColorNames
.getConstArray();
366 sal_Int32 nIndex
= 0;
367 for(int i
= 0; i
< ColorConfigEntryCount
&& aColorNames
.getLength() > nIndex
; ++i
)
369 pPropValues
[nIndex
].Name
= pColorNames
[nIndex
];
370 //save automatic colors as void value
371 if(m_aConfigValues
[i
].nColor
!= COL_AUTO
)
372 pPropValues
[nIndex
].Value
<<= m_aConfigValues
[i
].nColor
;
375 if(nIndex
>= aColorNames
.getLength())
377 //test for visibility property
378 if(pColorNames
[nIndex
].endsWith(g_sIsVisible
))
380 pPropValues
[nIndex
].Name
= pColorNames
[nIndex
];
381 pPropValues
[nIndex
].Value
<<= m_aConfigValues
[i
].bIsVisible
;
385 SetSetProperties(u
"ColorSchemes"_ustr
, aPropValues
);
387 CommitCurrentSchemeName();
390 void ColorConfig_Impl::CommitCurrentSchemeName()
392 //save current scheme name
393 uno::Sequence
< OUString
> aCurrent
{ u
"CurrentColorScheme"_ustr
};
394 uno::Sequence
< uno::Any
> aCurrentVal(1);
395 aCurrentVal
.getArray()[0] <<= m_sLoadedScheme
;
396 PutProperties(aCurrent
, aCurrentVal
);
397 ThemeColors::GetThemeColors().SetThemeName(m_sLoadedScheme
);
400 void ColorConfig_Impl::SetColorConfigValue(ColorConfigEntry eValue
, const ColorConfigValue
& rValue
)
402 if(rValue
!= m_aConfigValues
[eValue
])
404 m_aConfigValues
[eValue
] = rValue
;
409 uno::Sequence
< OUString
> ColorConfig_Impl::GetSchemeNames()
411 return GetNodeNames(u
"ColorSchemes"_ustr
);
414 void ColorConfig_Impl::AddScheme(const OUString
& rScheme
)
416 if(ConfigItem::AddNode(u
"ColorSchemes"_ustr
, rScheme
))
418 m_sLoadedScheme
= rScheme
;
423 void ColorConfig_Impl::RemoveScheme(const OUString
& rScheme
)
425 uno::Sequence
< OUString
> aElements
{ rScheme
};
426 ClearNodeElements(u
"ColorSchemes"_ustr
, aElements
);
429 void ColorConfig_Impl::SettingsChanged()
431 SolarMutexGuard aVclGuard
;
433 NotifyListeners(ConfigurationHints::NONE
);
436 IMPL_LINK( ColorConfig_Impl
, DataChangedEventListener
, VclSimpleEvent
&, rEvent
, void )
438 if ( rEvent
.GetId() == VclEventId::ApplicationDataChanged
)
440 DataChangedEvent
* pData
= static_cast<DataChangedEvent
*>(static_cast<VclWindowEvent
&>(rEvent
).GetData());
441 if ( (pData
->GetType() == DataChangedEventType::SETTINGS
) &&
442 (pData
->GetFlags() & AllSettingsFlags::STYLE
) )
449 // Loads the ThemeColors (ExpertConfig Colors) into static ThemeColors::maThemeColors
450 void ColorConfig::LoadThemeColorsFromRegistry()
452 ThemeColors
& rThemeColors
= ThemeColors::GetThemeColors();
454 rThemeColors
.SetWindowColor(m_pImpl
->GetColorConfigValue(svtools::WINDOWCOLOR
).nColor
);
455 rThemeColors
.SetWindowTextColor(m_pImpl
->GetColorConfigValue(svtools::WINDOWTEXTCOLOR
).nColor
);
456 rThemeColors
.SetBaseColor(m_pImpl
->GetColorConfigValue(svtools::BASECOLOR
).nColor
);
457 rThemeColors
.SetButtonColor(m_pImpl
->GetColorConfigValue(svtools::BUTTONCOLOR
).nColor
);
458 rThemeColors
.SetButtonTextColor(m_pImpl
->GetColorConfigValue(svtools::BUTTONTEXTCOLOR
).nColor
);
459 rThemeColors
.SetAccentColor(m_pImpl
->GetColorConfigValue(svtools::ACCENTCOLOR
).nColor
);
460 rThemeColors
.SetDisabledColor(m_pImpl
->GetColorConfigValue(svtools::DISABLEDCOLOR
).nColor
);
461 rThemeColors
.SetDisabledTextColor(m_pImpl
->GetColorConfigValue(svtools::DISABLEDTEXTCOLOR
).nColor
);
462 rThemeColors
.SetShadeColor(m_pImpl
->GetColorConfigValue(svtools::SHADECOLOR
).nColor
);
463 rThemeColors
.SetSeparatorColor(m_pImpl
->GetColorConfigValue(svtools::SEPARATORCOLOR
).nColor
);
464 rThemeColors
.SetFaceColor(m_pImpl
->GetColorConfigValue(svtools::FACECOLOR
).nColor
);
465 rThemeColors
.SetActiveColor(m_pImpl
->GetColorConfigValue(svtools::ACTIVECOLOR
).nColor
);
466 rThemeColors
.SetActiveTextColor(m_pImpl
->GetColorConfigValue(svtools::ACTIVETEXTCOLOR
).nColor
);
467 rThemeColors
.SetActiveBorderColor(m_pImpl
->GetColorConfigValue(svtools::ACTIVEBORDERCOLOR
).nColor
);
468 rThemeColors
.SetFieldColor(m_pImpl
->GetColorConfigValue(svtools::FIELDCOLOR
).nColor
);
469 rThemeColors
.SetMenuBarColor(m_pImpl
->GetColorConfigValue(svtools::MENUBARCOLOR
).nColor
);
470 rThemeColors
.SetMenuBarTextColor(m_pImpl
->GetColorConfigValue(svtools::MENUBARTEXTCOLOR
).nColor
);
471 rThemeColors
.SetMenuBarHighlightColor(m_pImpl
->GetColorConfigValue(svtools::MENUBARHIGHLIGHTCOLOR
).nColor
);
472 rThemeColors
.SetMenuBarHighlightTextColor(m_pImpl
->GetColorConfigValue(svtools::MENUBARHIGHLIGHTTEXTCOLOR
).nColor
);
473 rThemeColors
.SetMenuColor(m_pImpl
->GetColorConfigValue(svtools::MENUCOLOR
).nColor
);
474 rThemeColors
.SetMenuTextColor(m_pImpl
->GetColorConfigValue(svtools::MENUTEXTCOLOR
).nColor
);
475 rThemeColors
.SetMenuHighlightColor(m_pImpl
->GetColorConfigValue(svtools::MENUHIGHLIGHTCOLOR
).nColor
);
476 rThemeColors
.SetMenuHighlightTextColor(m_pImpl
->GetColorConfigValue(svtools::MENUHIGHLIGHTTEXTCOLOR
).nColor
);
477 rThemeColors
.SetMenuBorderColor(m_pImpl
->GetColorConfigValue(svtools::MENUBORDERCOLOR
).nColor
);
478 rThemeColors
.SetInactiveColor(m_pImpl
->GetColorConfigValue(svtools::INACTIVECOLOR
).nColor
);
479 rThemeColors
.SetInactiveTextColor(m_pImpl
->GetColorConfigValue(svtools::INACTIVETEXTCOLOR
).nColor
);
480 rThemeColors
.SetInactiveBorderColor(m_pImpl
->GetColorConfigValue(svtools::INACTIVEBORDERCOLOR
).nColor
);
481 rThemeColors
.SetThemeName(GetCurrentSchemeName());
483 ThemeColors::SetThemeLoaded(true);
486 void ColorConfig::SetupTheme()
488 if (!officecfg::Office::Common::Misc::LibreOfficeTheme::get()
489 || ThemeColors::IsAutomaticTheme(GetCurrentSchemeName()))
491 ThemeColors::SetThemeLoaded(false);
495 if (!ThemeColors::IsThemeLoaded())
497 // extension to registry
498 m_pImpl
->Load(GetCurrentSchemeName());
499 m_pImpl
->CommitCurrentSchemeName();
502 LoadThemeColorsFromRegistry();
506 ColorConfig::ColorConfig()
508 if (comphelper::IsFuzzing())
510 std::unique_lock
aGuard( ColorMutex_Impl() );
513 m_pImpl
= new ColorConfig_Impl
;
514 aGuard
.unlock(); // because holdConfigItem will call this constructor
515 svtools::ItemHolder2::holdConfigItem(EItem::ColorConfig
);
517 ++nColorRefCount_Impl
;
518 m_pImpl
->AddListener(this);
522 ColorConfig::~ColorConfig()
524 if (comphelper::IsFuzzing())
526 std::unique_lock
aGuard( ColorMutex_Impl() );
527 m_pImpl
->RemoveListener(this);
528 if(!--nColorRefCount_Impl
)
535 Color
ColorConfig::GetDefaultColor(ColorConfigEntry eEntry
, int nMod
)
537 // the actual value of default color doesn't matter for colors in Group_Application
538 // and this is just to prevent index out of bound error.
539 if (eEntry
>= WINDOWCOLOR
)
542 enum ColorType
{ clLight
= 0,
546 static const Color cAutoColors
[][nColorTypes
] =
548 { COL_WHITE
, Color(0x1C1C1C) }, // DOCCOLOR
549 { COL_LIGHTGRAY
, Color(0x808080) }, // DOCBOUNDARIES
550 { Color(0xDFDFDE), Color(0x333333) }, // APPBACKGROUND
551 { COL_LIGHTGRAY
, Color(0x808080) }, // TABLEBOUNDARIES
552 { COL_BLACK
, COL_BLACK
}, // FONTCOLOR
553 { COL_BLUE
, Color(0x1D99F3) }, // LINKS
554 { Color(0x0000cc), Color(0x9B59B6) }, // LINKSVISITED
555 { COL_LIGHTRED
, Color(0xC9211E) }, // SPELL
556 { COL_LIGHTBLUE
, Color(0x729FCF) }, // GRAMMAR
557 { COL_LIGHTMAGENTA
, Color(0x780373) }, // SMARTTAGS
558 { COL_GRAY
, Color(0x1C1C1C) }, // SHADOWCOLOR
559 { COL_LIGHTGRAY
, Color(0x808080) }, // WRITERTEXTGRID
560 { COL_LIGHTGRAY
, COL_LIGHTGRAY
}, // WRITERFIELDSHADING
561 { COL_LIGHTGRAY
, Color(0x1C1C1C) }, // WRITERIDXSHADINGS
562 { COL_BLACK
, COL_BLACK
}, // WRITERDIRECTCURSOR
563 { COL_GREEN
, Color(0x1E6A39) }, // WRITERSCRIPTINDICATOR
564 { COL_LIGHTGRAY
, Color(0x808080) }, // WRITERSECTIONBOUNDARIES
565 { Color(0x0369a3), Color(0xB4C7DC) }, // WRITERHEADERFOOTERMARK
566 { COL_BLUE
, Color(0x729FCF) }, // WRITERPAGEBREAKS
567 { Color(0x268BD2), Color(0x268BD2) }, // WRITERNONPRINTCHARS
568 { COL_LIGHTBLUE
, COL_LIGHTBLUE
}, // HTMLSGML
569 { COL_LIGHTGREEN
, COL_LIGHTGREEN
}, // HTMLCOMMENT
570 { COL_LIGHTRED
, COL_LIGHTRED
}, // HTMLKEYWORD
571 { COL_GRAY
, COL_GRAY
}, // HTMLUNKNOWN
572 { COL_GRAY3
, COL_GRAY7
}, // CALCGRID
573 { COL_LIGHTBLUE
, COL_LIGHTBLUE
}, // CALCCELLFOCUS
574 { COL_BLUE
, COL_BLUE
}, // CALCPAGEBREAK
575 { Color(0x2300dc), Color(0x2300DC) }, // CALCPAGEBREAKMANUAL
576 { COL_GRAY7
, COL_GRAY7
}, // CALCPAGEBREAKAUTOMATIC
577 { Color(0x2300dc), Color(0x2300DC) }, // CALCHIDDENCOLROW
578 { COL_LIGHTRED
, COL_LIGHTRED
}, // CALCTEXTOVERFLOW
579 { Color(0xbf819e), Color(0xbf819e) }, // CALCCOMMENT
580 { COL_LIGHTBLUE
, Color(0x355269) }, // CALCDETECTIVE
581 { COL_LIGHTRED
, Color(0xC9211E) }, // CALCDETECTIVEERROR
582 { Color(0xef0fff), Color(0x0D23D5) }, // CALCREFERENCE
583 { Color(0xffffc0), Color(0xE8A202) }, // CALCNOTESBACKGROUND
584 { COL_LIGHTBLUE
, Color(0x729FCF) }, // CALCVALUE
585 { COL_GREEN
, Color(0x77BC65) }, // CALCFORMULA
586 { COL_BLACK
, Color(0xEEEEEE) }, // CALCTEXT
587 { COL_LIGHTGRAY
, Color(0x1C1C1C) }, // CALCPROTECTEDBACKGROUND
588 { COL_GRAY7
, COL_GRAY7
}, // DRAWGRID
589 { Color(0xC69200), Color(0xffffa6) }, // AUTHOR1
590 { Color(0x0646A2), Color(0xb4c7dc) }, // AUTHOR2
591 { Color(0x579D1C), Color(0xffa6a6) }, // AUTHOR3
592 { Color(0x692B9D), Color(0xafd095) }, // AUTHOR4
593 { Color(0xC5000B), Color(0xffb66c) }, // AUTHOR5
594 { Color(0x008080), Color(0xbf819e) }, // AUTHOR6
595 { Color(0x8C8400), Color(0xd4ea6b) }, // AUTHOR7
596 { Color(0x35556B), Color(0xe8a202) }, // AUTHOR8
597 { Color(0xD17600), Color(0x5983b0) }, // AUTHOR9
598 { COL_WHITE
, Color(0x1C1C1C) }, // BASICEDITOR
599 { COL_GREEN
, Color(0xDDE8CB) }, // BASICIDENTIFIER
600 { COL_GRAY
, Color(0xEEEEEE) }, // BASICCOMMENT
601 { COL_LIGHTRED
, Color(0xFFA6A6) }, // BASICNUMBER
602 { COL_LIGHTRED
, Color(0xFFA6A6) }, // BASICSTRING
603 { COL_BLUE
, Color(0xB4C7DC) }, // BASICOPERATOR
604 { COL_BLUE
, Color(0xB4C7DC) }, // BASICKEYWORD
605 { COL_RED
, Color(0xFF3838) }, // BASICERROR
606 { Color(0x009900), Color(0x009900) }, // SQLIDENTIFIER
607 { COL_BLACK
, COL_BLACK
}, // SQLNUMBER
608 { Color(0xCE7B00), Color(0xCE7B00) }, // SQLSTRING
609 { COL_BLACK
, COL_BLACK
}, // SQLOPERATOR
610 { Color(0x0000E6), Color(0x0000E6) }, // SQLKEYWORD
611 { Color(0x259D9D), Color(0x259D9D) }, // SQLPARAMETER
612 { COL_GRAY
, COL_GRAY
}, // SQLCOMMENT
618 aRet
= Application::GetSettings().GetStyleSettings().GetWorkspaceColor();
622 aRet
= Application::GetSettings().GetStyleSettings().GetLinkColor();
626 aRet
= Application::GetSettings().GetStyleSettings().GetVisitedLinkColor();
630 aRet
= Application::GetSettings().GetStyleSettings().GetAccentColor();
642 switch (MiscSettings::GetAppColorMode()) {
644 if (MiscSettings::GetUseDarkMode())
649 case 1: nAppMod
= clLight
; break;
650 case 2: nAppMod
= clDark
; break;
653 aRet
= cAutoColors
[eEntry
][nAppMod
];
655 // fdo#71511: if in a11y HC mode, do pull background color from theme
656 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() && nMod
== -1)
661 aRet
= Application::GetSettings().GetStyleSettings().GetWindowColor();
664 aRet
= Application::GetSettings().GetStyleSettings().GetWindowTextColor();
673 ColorConfigValue
ColorConfig::GetColorValue(ColorConfigEntry eEntry
, bool bSmart
) const
675 ColorConfigValue aRet
;
678 aRet
= m_pImpl
->GetColorConfigValue(eEntry
);
680 if (bSmart
&& aRet
.nColor
== COL_AUTO
)
681 aRet
.nColor
= ColorConfig::GetDefaultColor(eEntry
);
686 const OUString
& ColorConfig::GetCurrentSchemeName()
688 uno::Sequence
<OUString
> aNames
= m_pImpl
->GetSchemeNames();
689 OUString aCurrentSchemeName
= officecfg::Office::UI::ColorScheme::CurrentColorScheme::get().value();
691 for (const OUString
& rSchemeName
: aNames
)
692 if (rSchemeName
== aCurrentSchemeName
)
693 return m_pImpl
->GetLoadedScheme();
695 // Use "Automatic" as fallback
696 auto pChange(comphelper::ConfigurationChanges::create());
697 officecfg::Office::UI::ColorScheme::CurrentColorScheme::set(AUTOMATIC_COLOR_SCHEME
, pChange
);
700 m_pImpl
->SetCurrentSchemeName(AUTOMATIC_COLOR_SCHEME
);
701 return m_pImpl
->GetLoadedScheme();
704 EditableColorConfig::EditableColorConfig() :
705 m_pImpl(new ColorConfig_Impl
),
708 m_pImpl
->BlockBroadcasts(true);
711 EditableColorConfig::~EditableColorConfig()
713 m_pImpl
->BlockBroadcasts(false);
715 m_pImpl
->SetModified();
716 if(m_pImpl
->IsModified())
720 uno::Sequence
< OUString
> EditableColorConfig::GetSchemeNames() const
722 return m_pImpl
->GetSchemeNames();
725 void EditableColorConfig::DeleteScheme(const OUString
& rScheme
)
727 m_pImpl
->RemoveScheme(rScheme
);
730 void EditableColorConfig::AddScheme(const OUString
& rScheme
)
732 m_pImpl
->AddScheme(rScheme
);
735 void EditableColorConfig::LoadScheme(const OUString
& rScheme
)
738 m_pImpl
->SetModified();
739 if(m_pImpl
->IsModified())
742 m_pImpl
->Load(rScheme
);
743 //the name of the loaded scheme has to be committed separately
744 m_pImpl
->CommitCurrentSchemeName();
747 const OUString
& EditableColorConfig::GetCurrentSchemeName()const
749 return m_pImpl
->GetLoadedScheme();
752 // Changes the name of the current scheme but doesn't load it!
753 void EditableColorConfig::SetCurrentSchemeName(const OUString
& rScheme
)
755 m_pImpl
->SetCurrentSchemeName(rScheme
);
756 m_pImpl
->CommitCurrentSchemeName();
759 const ColorConfigValue
& EditableColorConfig::GetColorValue(
760 ColorConfigEntry eEntry
)const
762 return m_pImpl
->GetColorConfigValue(eEntry
);
765 void EditableColorConfig::SetColorValue(
766 ColorConfigEntry eEntry
, const ColorConfigValue
& rValue
)
768 m_pImpl
->SetColorConfigValue(eEntry
, rValue
);
769 m_pImpl
->ClearModified();
773 void EditableColorConfig::SetModified()
778 void EditableColorConfig::Commit()
781 m_pImpl
->SetModified();
782 if(m_pImpl
->IsModified())
787 void EditableColorConfig::DisableBroadcast()
789 m_pImpl
->BlockBroadcasts(true);
792 void EditableColorConfig::EnableBroadcast()
794 m_pImpl
->BlockBroadcasts(false);
800 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */