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