Bump version to 5.0-14
[LibreOffice.git] / svtools / source / config / colorcfg.cxx
blob9689be680ff17e12765947d6055e4b61fd0d69f4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include <svtools/colorcfg.hxx>
22 #include <com/sun/star/uno/Any.hxx>
23 #include <com/sun/star/uno/Sequence.hxx>
24 #include <com/sun/star/lang/Locale.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <comphelper/processfactory.hxx>
27 #include <unotools/configitem.hxx>
28 #include <unotools/confignode.hxx>
29 #include <unotools/configpaths.hxx>
30 #include <com/sun/star/uno/Sequence.h>
31 #include <svl/poolitem.hxx>
32 #include <svl/smplhint.hxx>
33 #include <osl/mutex.hxx>
35 #include "itemholder2.hxx"
37 /* #100822# ----
38 #include <vcl/wrkwin.hxx>
39 ------------- */
40 #include <vcl/svapp.hxx>
41 #include <vcl/event.hxx>
42 #include <vcl/settings.hxx>
43 #include <rtl/instance.hxx>
46 using namespace utl;
47 using namespace com::sun::star;
50 namespace svtools
53 static const sal_Char cColor[] = "/Color";
54 static const sal_Char cColorSchemes[] = "ColorSchemes/";
55 sal_Int32 nColorRefCount_Impl = 0;
56 namespace
58 struct ColorMutex_Impl
59 : public rtl::Static< ::osl::Mutex, ColorMutex_Impl > {};
62 ColorConfig_Impl* ColorConfig::m_pImpl = NULL;
64 class ColorConfig_Impl : public utl::ConfigItem
66 ColorConfigValue m_aConfigValues[ColorConfigEntryCount];
67 bool m_bEditMode;
68 OUString m_sIsVisible;
69 OUString m_sLoadedScheme;
70 bool m_bAutoDetectSystemHC;
72 uno::Sequence< OUString> GetPropertyNames(const OUString& rScheme);
74 virtual void ImplCommit() SAL_OVERRIDE;
76 public:
77 ColorConfig_Impl(bool bEditMode = false);
78 virtual ~ColorConfig_Impl();
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) SAL_OVERRIDE;
86 const ColorConfigValue& GetColorConfigValue(ColorConfigEntry eValue)
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 bool AddScheme(const OUString& rNode);
96 bool RemoveScheme(const OUString& rNode);
97 void SetModified(){ConfigItem::SetModified();}
98 void ClearModified(){ConfigItem::ClearModified();}
99 void SettingsChanged();
100 bool GetAutoDetectSystemHC() {return m_bAutoDetectSystemHC;}
102 // #100822#
103 DECL_LINK( DataChangedEventListener, VclWindowEvent* );
105 void ImplUpdateApplicationSettings();
108 uno::Sequence< OUString> ColorConfig_Impl::GetPropertyNames(const OUString& rScheme)
110 uno::Sequence<OUString> aNames(2 * ColorConfigEntryCount);
111 OUString* pNames = aNames.getArray();
112 struct ColorConfigEntryData_Impl
114 const sal_Char* cName;
115 sal_Int32 nLength;
116 rtl_TextEncoding eEncoding;
117 bool bCanBeVisible;
119 static const ColorConfigEntryData_Impl cNames[] =
121 { RTL_CONSTASCII_USTRINGPARAM("/DocColor") ,false },
122 { RTL_CONSTASCII_USTRINGPARAM("/DocBoundaries") ,true },
123 { RTL_CONSTASCII_USTRINGPARAM("/AppBackground") ,false },
124 { RTL_CONSTASCII_USTRINGPARAM("/ObjectBoundaries"),true },
125 { RTL_CONSTASCII_USTRINGPARAM("/TableBoundaries") ,true },
126 { RTL_CONSTASCII_USTRINGPARAM("/FontColor") ,false },
127 { RTL_CONSTASCII_USTRINGPARAM("/Links") ,true },
128 { RTL_CONSTASCII_USTRINGPARAM("/LinksVisited") ,true },
129 { RTL_CONSTASCII_USTRINGPARAM("/Spell") ,false },
130 { RTL_CONSTASCII_USTRINGPARAM("/SmartTags") ,false },
131 { RTL_CONSTASCII_USTRINGPARAM("/Shadow") , true },
132 { RTL_CONSTASCII_USTRINGPARAM("/WriterTextGrid") ,false },
133 { RTL_CONSTASCII_USTRINGPARAM("/WriterFieldShadings"),true },
134 { RTL_CONSTASCII_USTRINGPARAM("/WriterIdxShadings") ,true },
135 { RTL_CONSTASCII_USTRINGPARAM("/WriterDirectCursor") ,true },
136 { RTL_CONSTASCII_USTRINGPARAM("/WriterScriptIndicator") ,false },
137 { RTL_CONSTASCII_USTRINGPARAM("/WriterSectionBoundaries") ,true },
138 { RTL_CONSTASCII_USTRINGPARAM("/WriterHeaderFooterMark") ,false },
139 { RTL_CONSTASCII_USTRINGPARAM("/WriterPageBreaks") ,false },
140 { RTL_CONSTASCII_USTRINGPARAM("/HTMLSGML") ,false },
141 { RTL_CONSTASCII_USTRINGPARAM("/HTMLComment") ,false },
142 { RTL_CONSTASCII_USTRINGPARAM("/HTMLKeyword") ,false },
143 { RTL_CONSTASCII_USTRINGPARAM("/HTMLUnknown") ,false },
144 { RTL_CONSTASCII_USTRINGPARAM("/CalcGrid") ,false },
145 { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreak"), false },
146 { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreakManual"), false },
147 { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreakAutomatic"), false },
148 { RTL_CONSTASCII_USTRINGPARAM("/CalcDetective") ,false },
149 { RTL_CONSTASCII_USTRINGPARAM("/CalcDetectiveError") ,false },
150 { RTL_CONSTASCII_USTRINGPARAM("/CalcReference") ,false },
151 { RTL_CONSTASCII_USTRINGPARAM("/CalcNotesBackground") ,false },
152 { RTL_CONSTASCII_USTRINGPARAM("/DrawGrid") ,true },
153 { RTL_CONSTASCII_USTRINGPARAM("/BASICIdentifier"), false },
154 { RTL_CONSTASCII_USTRINGPARAM("/BASICComment") , false },
155 { RTL_CONSTASCII_USTRINGPARAM("/BASICNumber") , false },
156 { RTL_CONSTASCII_USTRINGPARAM("/BASICString") , false },
157 { RTL_CONSTASCII_USTRINGPARAM("/BASICOperator") , false },
158 { RTL_CONSTASCII_USTRINGPARAM("/BASICKeyword") , false },
159 { RTL_CONSTASCII_USTRINGPARAM("/BASICError"), false },
160 { RTL_CONSTASCII_USTRINGPARAM("/SQLIdentifier"), false },
161 { RTL_CONSTASCII_USTRINGPARAM("/SQLNumber"), false },
162 { RTL_CONSTASCII_USTRINGPARAM("/SQLString"), false },
163 { RTL_CONSTASCII_USTRINGPARAM("/SQLOperator"), false },
164 { RTL_CONSTASCII_USTRINGPARAM("/SQLKeyword"), false },
165 { RTL_CONSTASCII_USTRINGPARAM("/SQLParameter"), false },
166 { RTL_CONSTASCII_USTRINGPARAM("/SQLComment"), false }
168 int nIndex = 0;
169 OUString sColor = cColor;
170 OUString sBase(cColorSchemes);
171 sBase += utl::wrapConfigurationElementName(rScheme);
172 const int nCount = ColorConfigEntryCount;
173 for(sal_Int32 i = 0; i < 4 * nCount; i+= 4)
175 OUString sBaseName(sBase);
176 sal_Int32 nPos = i / 4;
177 sBaseName += OUString(cNames[nPos].cName, cNames[nPos].nLength, cNames[nPos].eEncoding);
178 pNames[nIndex] += sBaseName;
179 pNames[nIndex++] += sColor;
180 if(cNames[nPos].bCanBeVisible)
182 pNames[nIndex] += sBaseName;
183 pNames[nIndex++] += m_sIsVisible;
186 aNames.realloc(nIndex);
187 return aNames;
190 ColorConfig_Impl::ColorConfig_Impl(bool bEditMode) :
191 ConfigItem("Office.UI/ColorScheme"),
192 m_bEditMode(bEditMode),
193 m_sIsVisible("/IsVisible"),
194 m_bAutoDetectSystemHC(true)
196 if(!m_bEditMode)
198 //try to register on the root node - if possible
199 uno::Sequence < OUString > aNames(1);
200 EnableNotification( aNames );
202 Load(OUString());
204 ImplUpdateApplicationSettings();
206 // #100822#
207 ::Application::AddEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) );
211 ColorConfig_Impl::~ColorConfig_Impl()
213 // #100822#
214 ::Application::RemoveEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) );
217 void ColorConfig_Impl::Load(const OUString& rScheme)
219 OUString sScheme(rScheme);
220 if(sScheme.isEmpty())
222 //detect current scheme name
223 uno::Sequence < OUString > aCurrent(1);
224 aCurrent.getArray()[0] = "CurrentColorScheme";
225 uno::Sequence< uno::Any > aCurrentVal = GetProperties( aCurrent );
226 aCurrentVal.getConstArray()[0] >>= sScheme;
228 m_sLoadedScheme = sScheme;
230 uno::Sequence < OUString > aColorNames = GetPropertyNames(sScheme);
231 uno::Sequence< uno::Any > aColors = GetProperties( aColorNames );
232 const uno::Any* pColors = aColors.getConstArray();
233 const OUString* pColorNames = aColorNames.getConstArray();
234 sal_Int32 nIndex = 0;
235 for(int i = 0; i < 2 * ColorConfigEntryCount && aColors.getLength() > nIndex; i+= 2)
237 if(pColors[nIndex].hasValue())
238 pColors[nIndex] >>= m_aConfigValues[i / 2].nColor;
239 else
240 m_aConfigValues[i/2].nColor = COL_AUTO;
241 nIndex++;
242 if(nIndex >= aColors.getLength())
243 break;
244 //test for visibility property
245 if(pColorNames[nIndex].endsWith(m_sIsVisible))
246 m_aConfigValues[i / 2].bIsVisible = Any2Bool(pColors[nIndex++]);
248 // fdo#71511: check if we are running in a11y autodetect
250 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithComponentContext(comphelper::getProcessComponentContext(),OUString("org.openoffice.Office.Common/Accessibility") );
251 if(aNode.isValid())
253 uno::Any aValue = aNode.getNodeValue(OUString("AutoDetectSystemHC"));
254 aValue >>= m_bAutoDetectSystemHC;
259 void ColorConfig_Impl::Notify( const uno::Sequence<OUString>& )
261 //loading via notification always uses the default setting
262 Load(OUString());
263 NotifyListeners(0);
266 void ColorConfig_Impl::ImplCommit()
268 uno::Sequence < OUString > aColorNames = GetPropertyNames(m_sLoadedScheme);
269 uno::Sequence < beans::PropertyValue > aPropValues(aColorNames.getLength());
270 beans::PropertyValue* pPropValues = aPropValues.getArray();
271 const OUString* pColorNames = aColorNames.getConstArray();
272 sal_Int32 nIndex = 0;
273 const uno::Type& rBoolType = cppu::UnoType<bool>::get();
274 for(int i = 0; i < 2 * ColorConfigEntryCount && aColorNames.getLength() > nIndex; i+= 2)
276 pPropValues[nIndex].Name = pColorNames[nIndex];
277 //save automatic colors as void value
278 if(COL_AUTO != sal::static_int_cast<ColorData>(m_aConfigValues[i/2].nColor))
279 pPropValues[nIndex].Value <<= m_aConfigValues[i/2].nColor;
281 nIndex++;
282 if(nIndex >= aColorNames.getLength())
283 break;
284 //test for visibility property
285 if(pColorNames[nIndex].endsWith(m_sIsVisible))
287 pPropValues[nIndex].Name = pColorNames[nIndex];
288 pPropValues[nIndex].Value.setValue(&m_aConfigValues[i/2].bIsVisible, rBoolType);
289 nIndex++;
292 OUString sNode("ColorSchemes");
293 SetSetProperties(sNode, aPropValues);
295 CommitCurrentSchemeName();
298 void ColorConfig_Impl::CommitCurrentSchemeName()
300 //save current scheme name
301 uno::Sequence < OUString > aCurrent(1);
302 aCurrent.getArray()[0] = "CurrentColorScheme";
303 uno::Sequence< uno::Any > aCurrentVal(1);
304 aCurrentVal.getArray()[0] <<= m_sLoadedScheme;
305 PutProperties(aCurrent, aCurrentVal);
308 void ColorConfig_Impl::SetColorConfigValue(ColorConfigEntry eValue, const ColorConfigValue& rValue )
310 if(rValue != m_aConfigValues[eValue])
312 m_aConfigValues[eValue] = rValue;
313 SetModified();
317 uno::Sequence< OUString> ColorConfig_Impl::GetSchemeNames()
319 return GetNodeNames("ColorSchemes");
322 bool ColorConfig_Impl::AddScheme(const OUString& rScheme)
324 if(ConfigItem::AddNode("ColorSchemes", rScheme))
326 m_sLoadedScheme = rScheme;
327 Commit();
328 return true;
330 return false;
333 bool ColorConfig_Impl::RemoveScheme(const OUString& rScheme)
335 uno::Sequence< OUString > aElements(1);
336 aElements.getArray()[0] = rScheme;
337 return ClearNodeElements("ColorSchemes", aElements);
340 void ColorConfig_Impl::SettingsChanged()
342 SolarMutexGuard aVclGuard;
344 ImplUpdateApplicationSettings();
346 NotifyListeners(0);
349 IMPL_LINK( ColorConfig_Impl, DataChangedEventListener, VclWindowEvent*, pEvent )
351 if ( pEvent->GetId() == VCLEVENT_APPLICATION_DATACHANGED )
353 DataChangedEvent* pData = static_cast<DataChangedEvent*>(pEvent->GetData());
354 if ( (pData->GetType() == DataChangedEventType::SETTINGS) &&
355 (pData->GetFlags() & AllSettingsFlags::STYLE) )
357 SettingsChanged();
358 return 1L;
359 } else
360 return 0L;
361 } else
362 return 0L;
367 /** updates the font color in the vcl window settings */
368 void ColorConfig_Impl::ImplUpdateApplicationSettings()
370 Application* pApp = GetpApp();
371 if( pApp )
373 AllSettings aSettings = Application::GetSettings();
374 StyleSettings aStyleSettings( aSettings.GetStyleSettings() );
376 ColorConfigValue aRet = GetColorConfigValue(svtools::FONTCOLOR);
377 if(COL_AUTO == sal::static_int_cast<ColorData>(aRet.nColor))
378 aRet.nColor = ColorConfig::GetDefaultColor(svtools::FONTCOLOR).GetColor();
380 Color aFontColor(aRet.nColor);
382 if( aStyleSettings.GetFontColor() != aFontColor )
384 aStyleSettings.SetFontColor( aFontColor );
386 aSettings.SetStyleSettings( aStyleSettings );
387 Application::SetSettings( aSettings );
394 ColorConfig::ColorConfig()
396 ::osl::MutexGuard aGuard( ColorMutex_Impl::get() );
397 if ( !m_pImpl )
399 m_pImpl = new ColorConfig_Impl;
400 svtools::ItemHolder2::holdConfigItem(E_COLORCFG);
402 ++nColorRefCount_Impl;
403 m_pImpl->AddListener(this);
406 ColorConfig::~ColorConfig()
408 ::osl::MutexGuard aGuard( ColorMutex_Impl::get() );
409 m_pImpl->RemoveListener(this);
410 if(!--nColorRefCount_Impl)
412 delete m_pImpl;
413 m_pImpl = 0;
417 Color ColorConfig::GetDefaultColor(ColorConfigEntry eEntry)
419 static const sal_Int32 aAutoColors[] =
421 COL_WHITE, // DOCCOLOR
422 0xc0c0c0, // DOCBOUNDARIES
423 0xDFDFDE, // APPBACKGROUND
424 COL_LIGHTGRAY, // OBJECTBOUNDARIES
425 COL_LIGHTGRAY, // TABLEBOUNDARIES
426 COL_BLACK, // FONTCOLOR
427 COL_BLUE, // LINKS
428 0x0000cc, // LINKSVISITED
429 COL_LIGHTRED, // SPELL
430 COL_LIGHTMAGENTA,// SMARTTAGS
431 COL_GRAY, // SHADOWCOLOR
432 COL_LIGHTGRAY, // WRITERTEXTGRID
433 COL_LIGHTGRAY, // WRITERFIELDSHADIN
434 COL_LIGHTGRAY, // WRITERIDXSHADINGS
435 0, // WRITERDIRECTCURSOR
436 COL_GREEN, //WRITERSCRIPTINDICATOR
437 COL_LIGHTGRAY, //WRITERSECTIONBOUNDARIES
438 0x0369a3, //WRITERHEADERFOOTERMARK,
439 COL_BLUE, //WRITERPAGEBREAKS,
440 COL_LIGHTBLUE, // HTMLSGML
441 COL_LIGHTGREEN, // HTMLCOMMENT
442 COL_LIGHTRED, // HTMLKEYWORD
443 COL_GRAY, // HTMLUNKNOWN
444 COL_LIGHTGRAY, // CALCGRID
445 COL_BLUE, //CALCPAGEBREAK
446 0x2300dc, //CALCPAGEBREAKMANUAL
447 COL_GRAY, //CALCPAGEBREAKAUTOMATIC
448 COL_LIGHTBLUE, // CALCDETECTIVE
449 COL_LIGHTRED, // CALCDETECTIVEERROR
450 0xef0fff, // CALCREFERENCE
451 0xffffc0, // CALCNOTESBACKGROUND
452 COL_LIGHTGRAY, // DRAWGRID
453 COL_GREEN, // BASICIDENTIFIER,
454 COL_GRAY,// BASICCOMMENT ,
455 COL_LIGHTRED,// BASICNUMBER ,
456 COL_LIGHTRED,// BASICSTRING ,
457 COL_BLUE, // BASICOPERATOR ,
458 COL_BLUE, // BASICKEYWORD ,
459 COL_RED, //BASICERROR
460 0x009900, // SQLIDENTIFIER
461 0x000000, // SQLNUMBER
462 0xCE7B00, // SQLSTRING
463 0x000000, // SQLOPERATOR
464 0x0000E6, // SQLKEYWORD
465 0x259D9D, // SQLPARAMTER
466 0x969696,// SQLCOMMENT
468 Color aRet;
469 switch(eEntry)
471 case APPBACKGROUND :
472 aRet = Application::GetSettings().GetStyleSettings().GetWorkspaceColor();
473 break;
475 case LINKS :
476 aRet = Application::GetSettings().GetStyleSettings().GetLinkColor();
477 break;
479 case LINKSVISITED :
480 aRet = Application::GetSettings().GetStyleSettings().GetVisitedLinkColor();
481 break;
483 default:
484 aRet = aAutoColors[eEntry];
486 // fdo#71511: if in autodetected a11y HC mode, do pull background color from theme
487 if(m_pImpl && m_pImpl->GetAutoDetectSystemHC())
489 switch(eEntry)
491 case DOCCOLOR :
492 aRet = Application::GetSettings().GetStyleSettings().GetWindowColor();
493 break;
494 case FONTCOLOR :
495 aRet = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
496 break;
497 default:
498 break;
501 return aRet;
504 ColorConfigValue ColorConfig::GetColorValue(ColorConfigEntry eEntry, bool bSmart) const
506 ColorConfigValue aRet = m_pImpl->GetColorConfigValue(eEntry);
507 if(bSmart)
509 if(COL_AUTO == sal::static_int_cast<ColorData>(aRet.nColor))
510 aRet.nColor = ColorConfig::GetDefaultColor(eEntry).GetColor();
513 return aRet;
516 void ColorConfig::Reload()
518 m_pImpl->Load(OUString());
521 EditableColorConfig::EditableColorConfig() :
522 m_pImpl(new ColorConfig_Impl),
523 m_bModified(false)
525 m_pImpl->BlockBroadcasts(true);
528 EditableColorConfig::~EditableColorConfig()
530 m_pImpl->BlockBroadcasts(false);
531 if(m_bModified)
532 m_pImpl->SetModified();
533 if(m_pImpl->IsModified())
534 m_pImpl->Commit();
535 delete m_pImpl;
538 uno::Sequence< OUString > EditableColorConfig::GetSchemeNames() const
540 return m_pImpl->GetSchemeNames();
543 void EditableColorConfig::DeleteScheme(const OUString& rScheme )
545 m_pImpl->RemoveScheme(rScheme);
548 void EditableColorConfig::AddScheme(const OUString& rScheme )
550 m_pImpl->AddScheme(rScheme);
553 bool EditableColorConfig::LoadScheme(const OUString& rScheme )
555 if(m_bModified)
556 m_pImpl->SetModified();
557 if(m_pImpl->IsModified())
558 m_pImpl->Commit();
559 m_bModified = false;
560 m_pImpl->Load(rScheme);
561 //the name of the loaded scheme has to be committed separately
562 m_pImpl->CommitCurrentSchemeName();
563 return true;
566 const OUString& EditableColorConfig::GetCurrentSchemeName()const
568 return m_pImpl->GetLoadedScheme();
571 // Changes the name of the current scheme but doesn't load it!
572 void EditableColorConfig::SetCurrentSchemeName(const OUString& rScheme)
574 m_pImpl->SetCurrentSchemeName(rScheme);
575 m_pImpl->CommitCurrentSchemeName();
578 const ColorConfigValue& EditableColorConfig::GetColorValue(
579 ColorConfigEntry eEntry)const
581 return m_pImpl->GetColorConfigValue(eEntry);
584 void EditableColorConfig::SetColorValue(
585 ColorConfigEntry eEntry, const ColorConfigValue& rValue)
587 m_pImpl->SetColorConfigValue(eEntry, rValue);
588 m_pImpl->ClearModified();
589 m_bModified = true;
592 void EditableColorConfig::SetModified()
594 m_bModified = true;
597 void EditableColorConfig::Commit()
599 if(m_bModified)
600 m_pImpl->SetModified();
601 if(m_pImpl->IsModified())
602 m_pImpl->Commit();
603 m_bModified = false;
606 void EditableColorConfig::DisableBroadcast()
608 m_pImpl->BlockBroadcasts(true);
611 void EditableColorConfig::EnableBroadcast()
613 m_pImpl->BlockBroadcasts(false);
617 }//namespace svtools
619 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */