xref: /core/svtools/source/config/colorcfg.cxx (revision 16a90925)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <string_view>
23 
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>
36 #include <mutex>
37 #include <vcl/window.hxx>
38 
39 #include "itemholder2.hxx"
40 
41 #include <vcl/svapp.hxx>
42 #include <vcl/event.hxx>
43 #include <vcl/settings.hxx>
44 #include <officecfg/Office/UI.hxx>
45 
46 using namespace utl;
47 using namespace com::sun::star;
48 
49 const char g_sIsVisible[] = "/IsVisible";
50 
51 
52 namespace svtools
53 {
54 
55 static sal_Int32            nColorRefCount_Impl = 0;
56 namespace
57 {
ColorMutex_Impl()58     std::mutex& ColorMutex_Impl()
59     {
60         static std::mutex SINGLETON;
61         return SINGLETON;
62     }
63 }
64 
65 ColorConfig_Impl*    ColorConfig::m_pImpl = nullptr;
66 
67 class ColorConfig_Impl : public utl::ConfigItem
68 {
69     ColorConfigValue m_aConfigValues[ColorConfigEntryCount];
70     OUString         m_sLoadedScheme;
71 
72     virtual void                    ImplCommit() override;
73 
74 public:
75     explicit ColorConfig_Impl();
76     virtual ~ColorConfig_Impl() override;
77 
78     void                            Load(const OUString& rScheme);
79     void                            CommitCurrentSchemeName();
80     //changes the name of the current scheme but doesn't load it!
SetCurrentSchemeName(const OUString & rSchemeName)81     void                            SetCurrentSchemeName(const OUString& rSchemeName) {m_sLoadedScheme = rSchemeName;}
82     virtual void                    Notify( const uno::Sequence<OUString>& aPropertyNames) override;
83 
GetColorConfigValue(ColorConfigEntry eValue) const84     const ColorConfigValue&         GetColorConfigValue(ColorConfigEntry eValue) const
85                                                             {return m_aConfigValues[eValue];}
86     void                            SetColorConfigValue(ColorConfigEntry eValue,
87                                                             const ColorConfigValue& rValue );
88 
GetLoadedScheme() const89     const OUString&            GetLoadedScheme() const {return m_sLoadedScheme;}
90 
91     uno::Sequence< OUString> GetSchemeNames();
92 
93     void                            AddScheme(const OUString& rNode);
94     void                            RemoveScheme(const OUString& rNode);
95     using ConfigItem::SetModified;
96     using ConfigItem::ClearModified;
97     void                            SettingsChanged();
98 
99     DECL_LINK( DataChangedEventListener, VclSimpleEvent&, void );
100 };
101 
102 namespace {
103 
GetPropertyNames(std::u16string_view rScheme)104 uno::Sequence< OUString> GetPropertyNames(std::u16string_view rScheme)
105 {
106     struct ColorConfigEntryData_Impl
107     {
108         std::u16string_view cName;
109         bool            bCanBeVisible;
110     };
111     static const ColorConfigEntryData_Impl cNames[] =
112     {
113         { std::u16string_view(u"/DocColor")        ,false },
114         { std::u16string_view(u"/DocBoundaries")   ,true },
115         { std::u16string_view(u"/AppBackground")   ,false },
116         { std::u16string_view(u"/ObjectBoundaries"),true },
117         { std::u16string_view(u"/TableBoundaries") ,true },
118         { std::u16string_view(u"/FontColor")     ,false },
119         { std::u16string_view(u"/Links")           ,true },
120         { std::u16string_view(u"/LinksVisited")    ,true },
121         { std::u16string_view(u"/Spell")     ,false },
122         { std::u16string_view(u"/Grammar")     ,false },
123         { std::u16string_view(u"/SmartTags")     ,false },
124         { std::u16string_view(u"/Shadow")        , true },
125         { std::u16string_view(u"/WriterTextGrid")  ,false },
126         { std::u16string_view(u"/WriterFieldShadings"),true },
127         { std::u16string_view(u"/WriterIdxShadings")     ,true },
128         { std::u16string_view(u"/WriterDirectCursor")    ,true },
129         { std::u16string_view(u"/WriterScriptIndicator")    ,false },
130         { std::u16string_view(u"/WriterSectionBoundaries")    ,true },
131         { std::u16string_view(u"/WriterHeaderFooterMark")    ,false },
132         { std::u16string_view(u"/WriterPageBreaks")    ,false },
133         { std::u16string_view(u"/HTMLSGML")        ,false },
134         { std::u16string_view(u"/HTMLComment")     ,false },
135         { std::u16string_view(u"/HTMLKeyword")     ,false },
136         { std::u16string_view(u"/HTMLUnknown")     ,false },
137         { std::u16string_view(u"/CalcGrid")        ,false },
138         { std::u16string_view(u"/CalcCellFocus")        ,false },
139         { std::u16string_view(u"/CalcPageBreak"), false },
140         { std::u16string_view(u"/CalcPageBreakManual"), false },
141         { std::u16string_view(u"/CalcPageBreakAutomatic"), false },
142         { std::u16string_view(u"/CalcHiddenColRow"), true },
143         { std::u16string_view(u"/CalcTextOverflow"), true },
144         { std::u16string_view(u"/CalcComments"), false },
145         { std::u16string_view(u"/CalcDetective")   ,false },
146         { std::u16string_view(u"/CalcDetectiveError")   ,false },
147         { std::u16string_view(u"/CalcReference")   ,false },
148         { std::u16string_view(u"/CalcNotesBackground") ,false },
149         { std::u16string_view(u"/CalcValue") ,false },
150         { std::u16string_view(u"/CalcFormula") ,false },
151         { std::u16string_view(u"/CalcText") ,false },
152         { std::u16string_view(u"/CalcProtectedBackground") ,false },
153         { std::u16string_view(u"/DrawGrid")        ,true },
154         { std::u16string_view(u"/BASICEditor"),  false },
155         { std::u16string_view(u"/BASICIdentifier"),  false },
156         { std::u16string_view(u"/BASICComment")   ,  false },
157         { std::u16string_view(u"/BASICNumber")    ,  false },
158         { std::u16string_view(u"/BASICString")    ,  false },
159         { std::u16string_view(u"/BASICOperator")  ,  false },
160         { std::u16string_view(u"/BASICKeyword")   ,  false },
161         { std::u16string_view(u"/BASICError"),  false },
162         { std::u16string_view(u"/SQLIdentifier"),  false },
163         { std::u16string_view(u"/SQLNumber"),  false },
164         { std::u16string_view(u"/SQLString"),  false },
165         { std::u16string_view(u"/SQLOperator"),  false },
166         { std::u16string_view(u"/SQLKeyword"),  false },
167         { std::u16string_view(u"/SQLParameter"),  false },
168         { std::u16string_view(u"/SQLComment"),  false }
169     };
170 
171     uno::Sequence<OUString> aNames(2 * ColorConfigEntryCount);
172     OUString* pNames = aNames.getArray();
173     int nIndex = 0;
174     OUString sBase = "ColorSchemes/"
175                    + utl::wrapConfigurationElementName(rScheme);
176     for(sal_Int32 i = 0; i < ColorConfigEntryCount; ++i)
177     {
178         OUString sBaseName = sBase + cNames[i].cName;
179         pNames[nIndex++] = sBaseName + "/Color";
180         if(cNames[i].bCanBeVisible)
181         {
182             pNames[nIndex++] = sBaseName + g_sIsVisible;
183         }
184     }
185     aNames.realloc(nIndex);
186     return aNames;
187 }
188 
189 }
190 
ColorConfig_Impl()191 ColorConfig_Impl::ColorConfig_Impl() :
192     ConfigItem(u"Office.UI/ColorScheme"_ustr)
193 {
194     //try to register on the root node - if possible
195     uno::Sequence < OUString > aNames(1);
196     EnableNotification( aNames );
197 
198     if (!comphelper::IsFuzzing())
199         Load(OUString());
200 
201     ::Application::AddEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) );
202 
203 }
204 
~ColorConfig_Impl()205 ColorConfig_Impl::~ColorConfig_Impl()
206 {
207     ::Application::RemoveEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) );
208 }
209 
Load(const OUString & rScheme)210 void ColorConfig_Impl::Load(const OUString& rScheme)
211 {
212     OUString sScheme(rScheme);
213     if(sScheme.isEmpty())
214     {
215         //detect current scheme name
216         uno::Sequence < OUString > aCurrent { u"CurrentColorScheme"_ustr };
217         uno::Sequence< uno::Any > aCurrentVal = GetProperties( aCurrent );
218         aCurrentVal.getConstArray()[0] >>= sScheme;
219     }
220     m_sLoadedScheme = sScheme;
221 
222     uno::Sequence < OUString > aColorNames = GetPropertyNames(sScheme);
223     uno::Sequence< uno::Any > aColors = GetProperties( aColorNames );
224     const uno::Any* pColors = aColors.getConstArray();
225     const OUString* pColorNames = aColorNames.getConstArray();
226     sal_Int32 nIndex = 0;
227     for(int i = 0; i < ColorConfigEntryCount && aColors.getLength() > nIndex; ++i)
228     {
229         if(pColors[nIndex].hasValue())
230         {
231             Color nTmp;
232             pColors[nIndex] >>= nTmp;
233             m_aConfigValues[i].nColor = nTmp;
234         }
235         else
236             m_aConfigValues[i].nColor = COL_AUTO;
237         nIndex++;
238         if(nIndex >= aColors.getLength())
239             break;
240         //test for visibility property
241         if(pColorNames[nIndex].endsWith(g_sIsVisible))
242              m_aConfigValues[i].bIsVisible = Any2Bool(pColors[nIndex++]);
243     }
244 }
245 
Notify(const uno::Sequence<OUString> & rProperties)246 void ColorConfig_Impl::Notify(const uno::Sequence<OUString>& rProperties)
247 {
248     const bool bOnlyChangingCurrentColorScheme = rProperties.getLength() == 1 && rProperties[0] == "CurrentColorScheme";
249     const OUString sOldLoadedScheme = m_sLoadedScheme;
250 
251     //loading via notification always uses the default setting
252     Load(OUString());
253 
254     // If the name of the scheme hasn't changed, then there is no change to the
255     // global color scheme name, but Kit deliberately only changed the then
256     // current document when it last changed, so there are typically a mixture
257     // of documents with the original 'light' color scheme and the last changed
258     // color scheme 'dark'. Kit then tries to set the color scheme again to the
259     // last changed color scheme 'dark' to try and update a 'light' document
260     // that had opted out of the last change to 'dark'. So tag such an apparent
261     // null change attempt with 'OnlyCurrentDocumentColorScheme' to allow it to
262     // go through, but identify what that change is for, so the other color
263     // config listeners for whom it doesn't matter, can ignore it as an
264     // optimization.
265     const bool bOnlyCurrentDocumentColorScheme = bOnlyChangingCurrentColorScheme && sOldLoadedScheme == m_sLoadedScheme &&
266                                                  comphelper::LibreOfficeKit::isActive();
267     NotifyListeners(bOnlyCurrentDocumentColorScheme ? ConfigurationHints::OnlyCurrentDocumentColorScheme : ConfigurationHints::NONE);
268 }
269 
ImplCommit()270 void ColorConfig_Impl::ImplCommit()
271 {
272     uno::Sequence < OUString > aColorNames = GetPropertyNames(m_sLoadedScheme);
273     uno::Sequence < beans::PropertyValue > aPropValues(aColorNames.getLength());
274     beans::PropertyValue* pPropValues = aPropValues.getArray();
275     const OUString* pColorNames = aColorNames.getConstArray();
276     sal_Int32 nIndex = 0;
277     for(int i = 0; i < ColorConfigEntryCount && aColorNames.getLength() > nIndex; ++i)
278     {
279         pPropValues[nIndex].Name = pColorNames[nIndex];
280         //save automatic colors as void value
281         if(m_aConfigValues[i].nColor != COL_AUTO)
282             pPropValues[nIndex].Value <<= m_aConfigValues[i].nColor;
283 
284         nIndex++;
285         if(nIndex >= aColorNames.getLength())
286             break;
287         //test for visibility property
288         if(pColorNames[nIndex].endsWith(g_sIsVisible))
289         {
290              pPropValues[nIndex].Name = pColorNames[nIndex];
291              pPropValues[nIndex].Value <<= m_aConfigValues[i].bIsVisible;
292              nIndex++;
293         }
294     }
295     SetSetProperties(u"ColorSchemes"_ustr, aPropValues);
296 
297     CommitCurrentSchemeName();
298 }
299 
CommitCurrentSchemeName()300 void ColorConfig_Impl::CommitCurrentSchemeName()
301 {
302     //save current scheme name
303     uno::Sequence < OUString > aCurrent { u"CurrentColorScheme"_ustr };
304     uno::Sequence< uno::Any > aCurrentVal(1);
305     aCurrentVal.getArray()[0] <<= m_sLoadedScheme;
306     PutProperties(aCurrent, aCurrentVal);
307 }
308 
SetColorConfigValue(ColorConfigEntry eValue,const ColorConfigValue & rValue)309 void ColorConfig_Impl::SetColorConfigValue(ColorConfigEntry eValue, const ColorConfigValue& rValue )
310 {
311     if(rValue != m_aConfigValues[eValue])
312     {
313         m_aConfigValues[eValue] = rValue;
314         SetModified();
315     }
316 }
317 
GetSchemeNames()318 uno::Sequence< OUString> ColorConfig_Impl::GetSchemeNames()
319 {
320     return GetNodeNames(u"ColorSchemes"_ustr);
321 }
322 
AddScheme(const OUString & rScheme)323 void ColorConfig_Impl::AddScheme(const OUString& rScheme)
324 {
325     if(ConfigItem::AddNode(u"ColorSchemes"_ustr, rScheme))
326     {
327         m_sLoadedScheme = rScheme;
328         Commit();
329     }
330 }
331 
RemoveScheme(const OUString & rScheme)332 void ColorConfig_Impl::RemoveScheme(const OUString& rScheme)
333 {
334     uno::Sequence< OUString > aElements { rScheme };
335     ClearNodeElements(u"ColorSchemes"_ustr, aElements);
336 }
337 
SettingsChanged()338 void ColorConfig_Impl::SettingsChanged()
339 {
340     SolarMutexGuard aVclGuard;
341 
342     NotifyListeners(ConfigurationHints::NONE);
343 }
344 
IMPL_LINK(ColorConfig_Impl,DataChangedEventListener,VclSimpleEvent &,rEvent,void)345 IMPL_LINK( ColorConfig_Impl, DataChangedEventListener, VclSimpleEvent&, rEvent, void )
346 {
347     if ( rEvent.GetId() == VclEventId::ApplicationDataChanged )
348     {
349         DataChangedEvent* pData = static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(rEvent).GetData());
350         if ( (pData->GetType() == DataChangedEventType::SETTINGS) &&
351              (pData->GetFlags() & AllSettingsFlags::STYLE) )
352         {
353             SettingsChanged();
354         }
355     }
356 }
357 
ColorConfig()358 ColorConfig::ColorConfig()
359 {
360     if (comphelper::IsFuzzing())
361         return;
362     std::unique_lock aGuard( ColorMutex_Impl() );
363     if ( !m_pImpl )
364     {
365         m_pImpl = new ColorConfig_Impl;
366         aGuard.unlock(); // because holdConfigItem will call this constructor
367         svtools::ItemHolder2::holdConfigItem(EItem::ColorConfig);
368     }
369     ++nColorRefCount_Impl;
370     m_pImpl->AddListener(this);
371 }
372 
~ColorConfig()373 ColorConfig::~ColorConfig()
374 {
375     if (comphelper::IsFuzzing())
376         return;
377     std::unique_lock aGuard( ColorMutex_Impl() );
378     m_pImpl->RemoveListener(this);
379     if(!--nColorRefCount_Impl)
380     {
381         delete m_pImpl;
382         m_pImpl = nullptr;
383     }
384 }
385 
GetDefaultColor(ColorConfigEntry eEntry)386 Color ColorConfig::GetDefaultColor(ColorConfigEntry eEntry)
387 {
388     enum ColorType { clLight = 0,
389                      clDark,
390                      nColorTypes };
391 
392     static const Color cAutoColors[][nColorTypes] =
393     {
394         { COL_WHITE,        Color(0x1C1C1C) }, // DOCCOLOR
395         { COL_LIGHTGRAY,    Color(0x808080) }, // DOCBOUNDARIES
396         { Color(0xDFDFDE),  Color(0x333333) }, // APPBACKGROUND
397         { COL_LIGHTGRAY,    Color(0x808080) }, // OBJECTBOUNDARIES
398         { COL_LIGHTGRAY,    Color(0x1C1C1C) }, // TABLEBOUNDARIES
399         { COL_BLACK,        COL_BLACK       }, // FONTCOLOR
400         { COL_BLUE,         Color(0x1D99F3) }, // LINKS
401         { Color(0x0000cc),  Color(0x9B59B6) }, // LINKSVISITED
402         { COL_LIGHTRED,     Color(0xC9211E) }, // SPELL
403         { COL_LIGHTBLUE,    Color(0x729FCF) }, // GRAMMAR
404         { COL_LIGHTMAGENTA, Color(0x780373) }, // SMARTTAGS
405         { COL_GRAY,         Color(0x1C1C1C) }, // SHADOWCOLOR
406         { COL_LIGHTGRAY,    Color(0x808080) }, // WRITERTEXTGRID
407         { COL_LIGHTGRAY,    COL_LIGHTGRAY   }, // WRITERFIELDSHADING
408         { COL_LIGHTGRAY,    Color(0x1C1C1C) }, // WRITERIDXSHADINGS
409         { COL_BLACK,        COL_BLACK       }, // WRITERDIRECTCURSOR
410         { COL_GREEN,        Color(0x1E6A39) }, // WRITERSCRIPTINDICATOR
411         { COL_LIGHTGRAY,    Color(0x666666) }, // WRITERSECTIONBOUNDARIES
412         { Color(0x0369a3),  Color(0xB4C7DC) }, // WRITERHEADERFOOTERMARK
413         { COL_BLUE,         Color(0x729FCF) }, // WRITERPAGEBREAKS
414         { COL_LIGHTBLUE,    COL_LIGHTBLUE   }, // HTMLSGML
415         { COL_LIGHTGREEN,   COL_LIGHTGREEN  }, // HTMLCOMMENT
416         { COL_LIGHTRED,     COL_LIGHTRED    }, // HTMLKEYWORD
417         { COL_GRAY,         COL_GRAY        }, // HTMLUNKNOWN
418         { COL_GRAY3,        COL_GRAY7       }, // CALCGRID
419         { COL_LIGHTBLUE,    COL_LIGHTBLUE   }, // CALCCELLFOCUS
420         { COL_BLUE,         COL_BLUE        }, // CALCPAGEBREAK
421         { Color(0x2300dc),  Color(0x2300DC) }, // CALCPAGEBREAKMANUAL
422         { COL_GRAY7,        COL_GRAY7       }, // CALCPAGEBREAKAUTOMATIC
423         { Color(0x2300dc),  Color(0x2300DC) }, // CALCHIDDENCOLROW
424         { COL_LIGHTRED,     COL_LIGHTRED    }, // CALCTEXTOVERFLOW
425         { Color(0xbf819e),  Color(0xbf819e) }, // CALCCOMMENT
426         { COL_LIGHTBLUE,    Color(0x355269) }, // CALCDETECTIVE
427         { COL_LIGHTRED,     Color(0xC9211E) }, // CALCDETECTIVEERROR
428         { Color(0xef0fff),  Color(0x0D23D5) }, // CALCREFERENCE
429         { Color(0xffffc0),  Color(0xE8A202) }, // CALCNOTESBACKGROUND
430         { COL_LIGHTBLUE,    Color(0x729FCF) }, // CALCVALUE
431         { COL_GREEN,        Color(0x77BC65) }, // CALCFORMULA
432         { COL_BLACK,        Color(0xEEEEEE) }, // CALCTEXT
433         { COL_LIGHTGRAY,    Color(0x1C1C1C) }, // CALCPROTECTEDBACKGROUND
434         { COL_GRAY7,        COL_GRAY7       }, // DRAWGRID
435         { COL_WHITE,        Color(0x1C1C1C) }, // BASICEDITOR
436         { COL_GREEN,        Color(0xDDE8CB) }, // BASICIDENTIFIER
437         { COL_GRAY,         Color(0xEEEEEE) }, // BASICCOMMENT
438         { COL_LIGHTRED,     Color(0xFFA6A6) }, // BASICNUMBER
439         { COL_LIGHTRED,     Color(0xFFA6A6) }, // BASICSTRING
440         { COL_BLUE,         Color(0xB4C7DC) }, // BASICOPERATOR
441         { COL_BLUE,         Color(0xB4C7DC) }, // BASICKEYWORD
442         { COL_RED,          Color(0xFF3838) }, // BASICERROR
443         { Color(0x009900),  Color(0x009900) }, // SQLIDENTIFIER
444         { COL_BLACK,        COL_BLACK       }, // SQLNUMBER
445         { Color(0xCE7B00),  Color(0xCE7B00) }, // SQLSTRING
446         { COL_BLACK,        COL_BLACK       }, // SQLOPERATOR
447         { Color(0x0000E6),  Color(0x0000E6) }, // SQLKEYWORD
448         { Color(0x259D9D),  Color(0x259D9D) }, // SQLPARAMETER
449         { COL_GRAY,         COL_GRAY        }, // SQLCOMMENT
450     };
451     Color aRet;
452     switch(eEntry)
453     {
454         case APPBACKGROUND :
455             aRet = Application::GetSettings().GetStyleSettings().GetWorkspaceColor();
456             break;
457 
458         case LINKS :
459             aRet = Application::GetSettings().GetStyleSettings().GetLinkColor();
460             break;
461 
462         case LINKSVISITED :
463             aRet = Application::GetSettings().GetStyleSettings().GetVisitedLinkColor();
464             break;
465 
466         case CALCCELLFOCUS:
467             aRet = Application::GetSettings().GetStyleSettings().GetAccentColor();
468             break;
469 
470         default:
471             int nAppMod;
472             switch (MiscSettings::GetAppColorMode()) {
473                 default:
474                     if (MiscSettings::GetUseDarkMode())
475                         nAppMod = clDark;
476                     else
477                         nAppMod = clLight;
478                     break;
479                 case 1: nAppMod = clLight; break;
480                 case 2: nAppMod = clDark; break;
481             }
482             aRet = cAutoColors[eEntry][nAppMod];
483     }
484     // fdo#71511: if in a11y HC mode, do pull background color from theme
485     if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
486     {
487         switch(eEntry)
488         {
489             case DOCCOLOR :
490                 aRet = Application::GetSettings().GetStyleSettings().GetWindowColor();
491                 break;
492             case FONTCOLOR :
493                 aRet = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
494                 break;
495             default:
496                 break;
497         }
498     }
499     return aRet;
500 }
501 
GetColorValue(ColorConfigEntry eEntry,bool bSmart) const502 ColorConfigValue ColorConfig::GetColorValue(ColorConfigEntry eEntry, bool bSmart) const
503 {
504     ColorConfigValue aRet;
505 
506     if (m_pImpl)
507         aRet = m_pImpl->GetColorConfigValue(eEntry);
508 
509     if (bSmart && aRet.nColor == COL_AUTO)
510         aRet.nColor = ColorConfig::GetDefaultColor(eEntry);
511 
512     return aRet;
513 }
514 
GetCurrentSchemeName()515 const OUString& ColorConfig::GetCurrentSchemeName()
516 {
517     officecfg::Office::UI::ColorScheme::CurrentColorScheme::get();
518     return m_pImpl->GetLoadedScheme();
519 }
520 
EditableColorConfig()521 EditableColorConfig::EditableColorConfig() :
522     m_pImpl(new ColorConfig_Impl),
523     m_bModified(false)
524 {
525     m_pImpl->BlockBroadcasts(true);
526 }
527 
~EditableColorConfig()528 EditableColorConfig::~EditableColorConfig()
529 {
530     m_pImpl->BlockBroadcasts(false);
531     if(m_bModified)
532         m_pImpl->SetModified();
533     if(m_pImpl->IsModified())
534         m_pImpl->Commit();
535 }
536 
GetSchemeNames() const537 uno::Sequence< OUString >  EditableColorConfig::GetSchemeNames() const
538 {
539     return m_pImpl->GetSchemeNames();
540 }
541 
DeleteScheme(const OUString & rScheme)542 void EditableColorConfig::DeleteScheme(const OUString& rScheme )
543 {
544     m_pImpl->RemoveScheme(rScheme);
545 }
546 
AddScheme(const OUString & rScheme)547 void EditableColorConfig::AddScheme(const OUString& rScheme )
548 {
549     m_pImpl->AddScheme(rScheme);
550 }
551 
LoadScheme(const OUString & rScheme)552 void EditableColorConfig::LoadScheme(const OUString& rScheme )
553 {
554     if(m_bModified)
555         m_pImpl->SetModified();
556     if(m_pImpl->IsModified())
557         m_pImpl->Commit();
558     m_bModified = false;
559     m_pImpl->Load(rScheme);
560     //the name of the loaded scheme has to be committed separately
561     m_pImpl->CommitCurrentSchemeName();
562 }
563 
GetCurrentSchemeName() const564 const OUString& EditableColorConfig::GetCurrentSchemeName()const
565 {
566     return m_pImpl->GetLoadedScheme();
567 }
568 
569 // Changes the name of the current scheme but doesn't load it!
SetCurrentSchemeName(const OUString & rScheme)570 void EditableColorConfig::SetCurrentSchemeName(const OUString& rScheme)
571 {
572     m_pImpl->SetCurrentSchemeName(rScheme);
573     m_pImpl->CommitCurrentSchemeName();
574 }
575 
GetColorValue(ColorConfigEntry eEntry) const576 const ColorConfigValue& EditableColorConfig::GetColorValue(
577     ColorConfigEntry eEntry)const
578 {
579     return m_pImpl->GetColorConfigValue(eEntry);
580 }
581 
SetColorValue(ColorConfigEntry eEntry,const ColorConfigValue & rValue)582 void EditableColorConfig::SetColorValue(
583     ColorConfigEntry eEntry, const ColorConfigValue& rValue)
584 {
585     m_pImpl->SetColorConfigValue(eEntry, rValue);
586     m_pImpl->ClearModified();
587     m_bModified = true;
588 }
589 
SetModified()590 void EditableColorConfig::SetModified()
591 {
592     m_bModified = true;
593 }
594 
Commit()595 void EditableColorConfig::Commit()
596 {
597     if(m_bModified)
598         m_pImpl->SetModified();
599     if(m_pImpl->IsModified())
600         m_pImpl->Commit();
601     m_bModified = false;
602 }
603 
DisableBroadcast()604 void EditableColorConfig::DisableBroadcast()
605 {
606     m_pImpl->BlockBroadcasts(true);
607 }
608 
EnableBroadcast()609 void EditableColorConfig::EnableBroadcast()
610 {
611     m_pImpl->BlockBroadcasts(false);
612 }
613 
614 
615 }//namespace svtools
616 
617 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
618