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 .
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 <unotools/configitem.hxx>
27 #include <unotools/configpaths.hxx>
28 #include <com/sun/star/uno/Sequence.h>
29 #include <svl/poolitem.hxx>
30 #include <svl/smplhint.hxx>
31 #include <osl/mutex.hxx>
33 #include <itemholder2.hxx>
36 #include <vcl/wrkwin.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/event.hxx>
40 #include <rtl/instance.hxx>
42 //-----------------------------------------------------------------------------
44 using namespace com::sun::star
;
50 static const sal_Char cColor
[] = "/Color";
51 static const sal_Char cColorSchemes
[] = "ColorSchemes/";
52 sal_Int32 nColorRefCount_Impl
= 0;
55 struct ColorMutex_Impl
56 : public rtl::Static
< ::osl::Mutex
, ColorMutex_Impl
> {};
59 ColorConfig_Impl
* ColorConfig::m_pImpl
= NULL
;
61 class ColorConfig_Impl
: public utl::ConfigItem
63 ColorConfigValue m_aConfigValues
[ColorConfigEntryCount
];
65 OUString m_sIsVisible
;
66 OUString m_sLoadedScheme
;
68 uno::Sequence
< OUString
> GetPropertyNames(const OUString
& rScheme
);
70 ColorConfig_Impl(sal_Bool bEditMode
= sal_False
);
71 virtual ~ColorConfig_Impl();
73 void Load(const OUString
& rScheme
);
74 void CommitCurrentSchemeName();
75 //changes the name of the current scheme but doesn't load it!
76 void SetCurrentSchemeName(const OUString
& rSchemeName
) {m_sLoadedScheme
= rSchemeName
;}
77 virtual void Commit();
78 virtual void Notify( const uno::Sequence
<OUString
>& aPropertyNames
);
80 const ColorConfigValue
& GetColorConfigValue(ColorConfigEntry eValue
)
81 {return m_aConfigValues
[eValue
];}
82 void SetColorConfigValue(ColorConfigEntry eValue
,
83 const ColorConfigValue
& rValue
);
85 const OUString
& GetLoadedScheme() const {return m_sLoadedScheme
;}
87 uno::Sequence
< OUString
> GetSchemeNames();
89 sal_Bool
AddScheme(const OUString
& rNode
);
90 sal_Bool
RemoveScheme(const OUString
& rNode
);
91 void SetModified(){ConfigItem::SetModified();}
92 void ClearModified(){ConfigItem::ClearModified();}
93 void SettingsChanged();
96 DECL_LINK( DataChangedEventListener
, VclWindowEvent
* );
98 void ImplUpdateApplicationSettings();
101 uno::Sequence
< OUString
> ColorConfig_Impl::GetPropertyNames(const OUString
& rScheme
)
103 uno::Sequence
<OUString
> aNames(2 * ColorConfigEntryCount
);
104 OUString
* pNames
= aNames
.getArray();
105 struct ColorConfigEntryData_Impl
107 const sal_Char
* cName
;
109 rtl_TextEncoding eEncoding
;
110 sal_Bool bCanBeVisible
;
112 static const ColorConfigEntryData_Impl cNames
[] =
114 { RTL_CONSTASCII_USTRINGPARAM("/DocColor") ,sal_False
},
115 { RTL_CONSTASCII_USTRINGPARAM("/DocBoundaries") ,sal_True
},
116 { RTL_CONSTASCII_USTRINGPARAM("/AppBackground") ,sal_False
},
117 { RTL_CONSTASCII_USTRINGPARAM("/ObjectBoundaries"),sal_True
},
118 { RTL_CONSTASCII_USTRINGPARAM("/TableBoundaries") ,sal_True
},
119 { RTL_CONSTASCII_USTRINGPARAM("/FontColor") ,sal_False
},
120 { RTL_CONSTASCII_USTRINGPARAM("/Links") ,sal_True
},
121 { RTL_CONSTASCII_USTRINGPARAM("/LinksVisited") ,sal_True
},
122 { RTL_CONSTASCII_USTRINGPARAM("/Spell") ,sal_False
},
123 { RTL_CONSTASCII_USTRINGPARAM("/SmartTags") ,sal_False
},
124 { RTL_CONSTASCII_USTRINGPARAM("/Shadow") , sal_True
},
125 { RTL_CONSTASCII_USTRINGPARAM("/WriterTextGrid") ,sal_False
},
126 { RTL_CONSTASCII_USTRINGPARAM("/WriterFieldShadings"),sal_True
},
127 { RTL_CONSTASCII_USTRINGPARAM("/WriterIdxShadings") ,sal_True
},
128 { RTL_CONSTASCII_USTRINGPARAM("/WriterDirectCursor") ,sal_True
},
129 { RTL_CONSTASCII_USTRINGPARAM("/WriterScriptIndicator") ,sal_False
},
130 { RTL_CONSTASCII_USTRINGPARAM("/WriterSectionBoundaries") ,sal_True
},
131 { RTL_CONSTASCII_USTRINGPARAM("/WriterHeaderFooterMark") ,sal_False
},
132 { RTL_CONSTASCII_USTRINGPARAM("/WriterPageBreaks") ,sal_False
},
133 { RTL_CONSTASCII_USTRINGPARAM("/HTMLSGML") ,sal_False
},
134 { RTL_CONSTASCII_USTRINGPARAM("/HTMLComment") ,sal_False
},
135 { RTL_CONSTASCII_USTRINGPARAM("/HTMLKeyword") ,sal_False
},
136 { RTL_CONSTASCII_USTRINGPARAM("/HTMLUnknown") ,sal_False
},
137 { RTL_CONSTASCII_USTRINGPARAM("/CalcGrid") ,sal_False
},
138 { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreak"), sal_False
},
139 { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreakManual"), sal_False
},
140 { RTL_CONSTASCII_USTRINGPARAM("/CalcPageBreakAutomatic"), sal_False
},
141 { RTL_CONSTASCII_USTRINGPARAM("/CalcDetective") ,sal_False
},
142 { RTL_CONSTASCII_USTRINGPARAM("/CalcDetectiveError") ,sal_False
},
143 { RTL_CONSTASCII_USTRINGPARAM("/CalcReference") ,sal_False
},
144 { RTL_CONSTASCII_USTRINGPARAM("/CalcNotesBackground") ,sal_False
},
145 { RTL_CONSTASCII_USTRINGPARAM("/DrawGrid") ,sal_True
},
146 { RTL_CONSTASCII_USTRINGPARAM("/BASICIdentifier"), sal_False
},
147 { RTL_CONSTASCII_USTRINGPARAM("/BASICComment") , sal_False
},
148 { RTL_CONSTASCII_USTRINGPARAM("/BASICNumber") , sal_False
},
149 { RTL_CONSTASCII_USTRINGPARAM("/BASICString") , sal_False
},
150 { RTL_CONSTASCII_USTRINGPARAM("/BASICOperator") , sal_False
},
151 { RTL_CONSTASCII_USTRINGPARAM("/BASICKeyword") , sal_False
},
152 { RTL_CONSTASCII_USTRINGPARAM("/BASICError"), sal_False
},
153 { RTL_CONSTASCII_USTRINGPARAM("/SQLIdentifier"), sal_False
},
154 { RTL_CONSTASCII_USTRINGPARAM("/SQLNumber"), sal_False
},
155 { RTL_CONSTASCII_USTRINGPARAM("/SQLString"), sal_False
},
156 { RTL_CONSTASCII_USTRINGPARAM("/SQLOperator"), sal_False
},
157 { RTL_CONSTASCII_USTRINGPARAM("/SQLKeyword"), sal_False
},
158 { RTL_CONSTASCII_USTRINGPARAM("/SQLParameter"), sal_False
},
159 { RTL_CONSTASCII_USTRINGPARAM("/SQLComment"), sal_False
}
162 OUString sColor
= cColor
;
163 OUString
sBase(cColorSchemes
);
164 sBase
+= utl::wrapConfigurationElementName(rScheme
);
165 const int nCount
= ColorConfigEntryCount
;
166 for(sal_Int32 i
= 0; i
< 4 * nCount
; i
+= 4)
168 OUString
sBaseName(sBase
);
169 sal_Int32 nPos
= i
/ 4;
170 sBaseName
+= OUString(cNames
[nPos
].cName
, cNames
[nPos
].nLength
, cNames
[nPos
].eEncoding
);
171 pNames
[nIndex
] += sBaseName
;
172 pNames
[nIndex
++] += sColor
;
173 if(cNames
[nPos
].bCanBeVisible
)
175 pNames
[nIndex
] += sBaseName
;
176 pNames
[nIndex
++] += m_sIsVisible
;
179 aNames
.realloc(nIndex
);
183 ColorConfig_Impl::ColorConfig_Impl(sal_Bool bEditMode
) :
184 ConfigItem("Office.UI/ColorScheme"),
185 m_bEditMode(bEditMode
),
186 m_sIsVisible("/IsVisible")
190 //try to register on the root node - if possible
191 uno::Sequence
< OUString
> aNames(1);
192 EnableNotification( aNames
);
196 ImplUpdateApplicationSettings();
199 ::Application::AddEventListener( LINK(this, ColorConfig_Impl
, DataChangedEventListener
) );
203 ColorConfig_Impl::~ColorConfig_Impl()
206 ::Application::RemoveEventListener( LINK(this, ColorConfig_Impl
, DataChangedEventListener
) );
209 void ColorConfig_Impl::Load(const OUString
& rScheme
)
211 OUString
sScheme(rScheme
);
212 if(sScheme
.isEmpty())
214 //detect current scheme name
215 uno::Sequence
< OUString
> aCurrent(1);
216 aCurrent
.getArray()[0] = "CurrentColorScheme";
217 uno::Sequence
< uno::Any
> aCurrentVal
= GetProperties( aCurrent
);
218 aCurrentVal
.getConstArray()[0] >>= sScheme
;
220 m_sLoadedScheme
= sScheme
;
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
< 2 * ColorConfigEntryCount
&& aColors
.getLength() > nIndex
; i
+= 2)
229 if(pColors
[nIndex
].hasValue())
230 pColors
[nIndex
] >>= m_aConfigValues
[i
/ 2].nColor
;
232 m_aConfigValues
[i
/2].nColor
= COL_AUTO
;
234 if(nIndex
>= aColors
.getLength())
236 //test for visibility property
237 if(pColorNames
[nIndex
].match(m_sIsVisible
, pColorNames
[nIndex
].getLength() - m_sIsVisible
.getLength()))
238 m_aConfigValues
[i
/ 2].bIsVisible
= Any2Bool(pColors
[nIndex
++]);
242 void ColorConfig_Impl::Notify( const uno::Sequence
<OUString
>& )
244 //loading via notification always uses the default setting
249 void ColorConfig_Impl::Commit()
251 uno::Sequence
< OUString
> aColorNames
= GetPropertyNames(m_sLoadedScheme
);
252 uno::Sequence
< beans::PropertyValue
> aPropValues(aColorNames
.getLength());
253 beans::PropertyValue
* pPropValues
= aPropValues
.getArray();
254 const OUString
* pColorNames
= aColorNames
.getConstArray();
255 sal_Int32 nIndex
= 0;
256 const uno::Type
& rBoolType
= ::getBooleanCppuType();
257 for(int i
= 0; i
< 2 * ColorConfigEntryCount
&& aColorNames
.getLength() > nIndex
; i
+= 2)
259 pPropValues
[nIndex
].Name
= pColorNames
[nIndex
];
260 //save automatic colors as void value
261 if(COL_AUTO
!= sal::static_int_cast
<ColorData
>(m_aConfigValues
[i
/2].nColor
))
262 pPropValues
[nIndex
].Value
<<= m_aConfigValues
[i
/2].nColor
;
265 if(nIndex
>= aColorNames
.getLength())
267 //test for visibility property
268 if(pColorNames
[nIndex
].match(m_sIsVisible
, pColorNames
[nIndex
].getLength() - m_sIsVisible
.getLength()))
270 pPropValues
[nIndex
].Name
= pColorNames
[nIndex
];
271 pPropValues
[nIndex
].Value
.setValue(&m_aConfigValues
[i
/2].bIsVisible
, rBoolType
);
275 OUString
sNode("ColorSchemes");
276 SetSetProperties(sNode
, aPropValues
);
278 CommitCurrentSchemeName();
281 void ColorConfig_Impl::CommitCurrentSchemeName()
283 //save current scheme name
284 uno::Sequence
< OUString
> aCurrent(1);
285 aCurrent
.getArray()[0] = "CurrentColorScheme";
286 uno::Sequence
< uno::Any
> aCurrentVal(1);
287 aCurrentVal
.getArray()[0] <<= m_sLoadedScheme
;
288 PutProperties(aCurrent
, aCurrentVal
);
291 void ColorConfig_Impl::SetColorConfigValue(ColorConfigEntry eValue
, const ColorConfigValue
& rValue
)
293 if(rValue
!= m_aConfigValues
[eValue
])
295 m_aConfigValues
[eValue
] = rValue
;
300 uno::Sequence
< OUString
> ColorConfig_Impl::GetSchemeNames()
302 return GetNodeNames("ColorSchemes");
305 sal_Bool
ColorConfig_Impl::AddScheme(const OUString
& rScheme
)
307 if(ConfigItem::AddNode("ColorSchemes", rScheme
))
309 m_sLoadedScheme
= rScheme
;
316 sal_Bool
ColorConfig_Impl::RemoveScheme(const OUString
& rScheme
)
318 uno::Sequence
< OUString
> aElements(1);
319 aElements
.getArray()[0] = rScheme
;
320 return ClearNodeElements("ColorSchemes", aElements
);
323 void ColorConfig_Impl::SettingsChanged()
325 SolarMutexGuard aVclGuard
;
327 ImplUpdateApplicationSettings();
332 IMPL_LINK( ColorConfig_Impl
, DataChangedEventListener
, VclWindowEvent
*, pEvent
)
334 if ( pEvent
->GetId() == VCLEVENT_APPLICATION_DATACHANGED
)
336 DataChangedEvent
* pData
= (DataChangedEvent
*)(pEvent
->GetData());
337 if ( (pData
->GetType() == DATACHANGED_SETTINGS
) &&
338 (pData
->GetFlags() & SETTINGS_STYLE
) )
348 // ---------------------------------------------------------------------------
350 /** updates the font color in the vcl window settings */
351 void ColorConfig_Impl::ImplUpdateApplicationSettings()
353 Application
* pApp
= GetpApp();
356 AllSettings aSettings
= pApp
->GetSettings();
357 StyleSettings
aStyleSettings( aSettings
.GetStyleSettings() );
359 ColorConfigValue aRet
= GetColorConfigValue(svtools::FONTCOLOR
);
360 if(COL_AUTO
== sal::static_int_cast
<ColorData
>(aRet
.nColor
))
361 aRet
.nColor
= ColorConfig::GetDefaultColor(svtools::FONTCOLOR
).GetColor();
363 Color
aFontColor(aRet
.nColor
);
365 if( aStyleSettings
.GetFontColor() != aFontColor
)
367 aStyleSettings
.SetFontColor( aFontColor
);
369 aSettings
.SetStyleSettings( aStyleSettings
);
370 pApp
->SetSettings( aSettings
);
375 // ---------------------------------------------------------------------------
377 ColorConfig::ColorConfig()
379 ::osl::MutexGuard
aGuard( ColorMutex_Impl::get() );
382 m_pImpl
= new ColorConfig_Impl
;
383 svtools::ItemHolder2::holdConfigItem(E_COLORCFG
);
385 ++nColorRefCount_Impl
;
386 m_pImpl
->AddListener(this);
389 ColorConfig::~ColorConfig()
391 ::osl::MutexGuard
aGuard( ColorMutex_Impl::get() );
392 m_pImpl
->RemoveListener(this);
393 if(!--nColorRefCount_Impl
)
400 Color
ColorConfig::GetDefaultColor(ColorConfigEntry eEntry
)
402 static const sal_Int32 aAutoColors
[] =
404 COL_WHITE
, // DOCCOLOR
405 0xc0c0c0, // DOCBOUNDARIES
406 0x808080, // APPBACKGROUND
407 0xc0c0c0, // OBJECTBOUNDARIES
408 0xc0c0c0, // TABLEBOUNDARIES
409 COL_BLACK
, // FONTCOLOR
411 0x80, // LINKSVISITED
413 COL_LIGHTMAGENTA
,// SMARTTAGS
414 COL_GRAY
, // SHADOWCOLOR
415 0xc0c0c0, // WRITERTEXTGRID
416 0xc0c0c0, // WRITERFIELDSHADIN
417 0xc0c0c0, // WRITERIDXSHADINGS
418 0, // WRITERDIRECTCURSOR
419 COL_GREEN
, //WRITERSCRIPTINDICATOR
420 0xc0c0c0, //WRITERSECTIONBOUNDARIES
421 0x0369a3, //WRITERHEADERFOOTERMARK,
422 COL_BLUE
, //WRITERPAGEBREAKS,
423 COL_LIGHTBLUE
, // HTMLSGML
424 COL_LIGHTGREEN
, // HTMLCOMMENT
425 COL_LIGHTRED
, // HTMLKEYWORD
426 COL_GRAY
, // HTMLUNKNOWN
427 COL_LIGHTGRAY
, // CALCGRID
428 COL_BLUE
, //CALCPAGEBREAK
429 0x2300dc, //CALCPAGEBREAKMANUAL
430 COL_GRAY
, //CALCPAGEBREAKAUTOMATIC
431 COL_LIGHTBLUE
, // CALCDETECTIVE
432 COL_LIGHTRED
, // CALCDETECTIVEERROR
433 COL_LIGHTRED
, // CALCREFERENCE
434 0xffffc0, // CALCNOTESBACKGROUND
435 0xc0c0c0, // DRAWGRID
436 COL_GREEN
, // BASICIDENTIFIER,
437 COL_GRAY
,// BASICCOMMENT ,
438 COL_LIGHTRED
,// BASICNUMBER ,
439 COL_LIGHTRED
,// BASICSTRING ,
440 COL_BLUE
, // BASICOPERATOR ,
441 COL_BLUE
, // BASICKEYWORD ,
442 COL_RED
, //BASICERROR
443 0x009900, // SQLIDENTIFIER
444 0x000000, // SQLNUMBER
445 0xCE7B00, // SQLSTRING
446 0x000000, // SQLOPERATOR
447 0x0000E6, // SQLKEYWORD
448 0x259D9D, // SQLPARAMTER
449 0x969696,// SQLCOMMENT
455 aRet
= Application::GetSettings().GetStyleSettings().GetWorkspaceColor();
459 aRet
= Application::GetSettings().GetStyleSettings().GetLinkColor();
463 aRet
= Application::GetSettings().GetStyleSettings().GetVisitedLinkColor();
467 aRet
= aAutoColors
[eEntry
];
472 ColorConfigValue
ColorConfig::GetColorValue(ColorConfigEntry eEntry
, sal_Bool bSmart
)const
474 ColorConfigValue aRet
= m_pImpl
->GetColorConfigValue(eEntry
);
477 if(COL_AUTO
== sal::static_int_cast
<ColorData
>(aRet
.nColor
))
478 aRet
.nColor
= ColorConfig::GetDefaultColor(eEntry
).GetColor();
484 EditableColorConfig::EditableColorConfig() :
485 m_pImpl(new ColorConfig_Impl
),
486 m_bModified(sal_False
)
488 m_pImpl
->BlockBroadcasts(sal_True
);
491 EditableColorConfig::~EditableColorConfig()
493 m_pImpl
->BlockBroadcasts(sal_False
);
495 m_pImpl
->SetModified();
496 if(m_pImpl
->IsModified())
501 uno::Sequence
< OUString
> EditableColorConfig::GetSchemeNames() const
503 return m_pImpl
->GetSchemeNames();
506 void EditableColorConfig::DeleteScheme(const OUString
& rScheme
)
508 m_pImpl
->RemoveScheme(rScheme
);
511 void EditableColorConfig::AddScheme(const OUString
& rScheme
)
513 m_pImpl
->AddScheme(rScheme
);
516 sal_Bool
EditableColorConfig::LoadScheme(const OUString
& rScheme
)
519 m_pImpl
->SetModified();
520 if(m_pImpl
->IsModified())
522 m_bModified
= sal_False
;
523 m_pImpl
->Load(rScheme
);
524 //the name of the loaded scheme has to be committed separately
525 m_pImpl
->CommitCurrentSchemeName();
529 const OUString
& EditableColorConfig::GetCurrentSchemeName()const
531 return m_pImpl
->GetLoadedScheme();
534 // Changes the name of the current scheme but doesn't load it!
535 void EditableColorConfig::SetCurrentSchemeName(const OUString
& rScheme
)
537 m_pImpl
->SetCurrentSchemeName(rScheme
);
538 m_pImpl
->CommitCurrentSchemeName();
541 const ColorConfigValue
& EditableColorConfig::GetColorValue(
542 ColorConfigEntry eEntry
)const
544 return m_pImpl
->GetColorConfigValue(eEntry
);
547 void EditableColorConfig::SetColorValue(
548 ColorConfigEntry eEntry
, const ColorConfigValue
& rValue
)
550 m_pImpl
->SetColorConfigValue(eEntry
, rValue
);
551 m_pImpl
->ClearModified();
552 m_bModified
= sal_True
;
555 void EditableColorConfig::SetModified()
557 m_bModified
= sal_True
;
560 void EditableColorConfig::Commit()
563 m_pImpl
->SetModified();
564 if(m_pImpl
->IsModified())
566 m_bModified
= sal_False
;
568 // -----------------------------------------------------------------------------
569 void EditableColorConfig::DisableBroadcast()
571 m_pImpl
->BlockBroadcasts(sal_True
);
573 // -----------------------------------------------------------------------------
574 void EditableColorConfig::EnableBroadcast()
576 m_pImpl
->BlockBroadcasts(sal_False
);
578 // -----------------------------------------------------------------------------
582 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */