OInterfaceContainerHelper3 needs to be thread-safe
[LibreOffice.git] / svl / source / config / ctloptions.cxx
blob0723f47ac1a19c7e2116215d4652d44954bc49aa
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 <svl/ctloptions.hxx>
23 #include <unotools/configitem.hxx>
24 #include <com/sun/star/uno/Any.h>
25 #include <com/sun/star/uno/Sequence.hxx>
26 #include <osl/mutex.hxx>
27 #include <rtl/instance.hxx>
28 #include "itemholder2.hxx"
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
33 #define CFG_READONLY_DEFAULT false
35 class SvtCTLOptions_Impl : public utl::ConfigItem
37 private:
38 bool m_bIsLoaded;
39 bool m_bCTLFontEnabled;
40 bool m_bCTLSequenceChecking;
41 bool m_bCTLRestricted;
42 bool m_bCTLTypeAndReplace;
43 SvtCTLOptions::CursorMovement m_eCTLCursorMovement;
44 SvtCTLOptions::TextNumerals m_eCTLTextNumerals;
46 bool m_bROCTLFontEnabled;
47 bool m_bROCTLSequenceChecking;
48 bool m_bROCTLRestricted;
49 bool m_bROCTLTypeAndReplace;
50 bool m_bROCTLCursorMovement;
51 bool m_bROCTLTextNumerals;
53 virtual void ImplCommit() override;
55 public:
56 SvtCTLOptions_Impl();
57 virtual ~SvtCTLOptions_Impl() override;
59 virtual void Notify( const Sequence< OUString >& _aPropertyNames ) override;
60 void Load();
62 bool IsLoaded() const { return m_bIsLoaded; }
63 void SetCTLFontEnabled( bool _bEnabled );
64 bool IsCTLFontEnabled() const { return m_bCTLFontEnabled; }
66 void SetCTLSequenceChecking( bool _bEnabled );
67 bool IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;}
69 void SetCTLSequenceCheckingRestricted( bool _bEnable );
70 bool IsCTLSequenceCheckingRestricted() const { return m_bCTLRestricted; }
72 void SetCTLSequenceCheckingTypeAndReplace( bool _bEnable );
73 bool IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace; }
75 void SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement );
76 SvtCTLOptions::CursorMovement
77 GetCTLCursorMovement() const { return m_eCTLCursorMovement; }
79 void SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals );
80 SvtCTLOptions::TextNumerals
81 GetCTLTextNumerals() const { return m_eCTLTextNumerals; }
83 bool IsReadOnly(SvtCTLOptions::EOption eOption) const;
85 namespace
87 struct PropertyNames
88 : public rtl::Static< Sequence< OUString >, PropertyNames > {};
90 bool SvtCTLOptions_Impl::IsReadOnly(SvtCTLOptions::EOption eOption) const
92 bool bReadOnly = CFG_READONLY_DEFAULT;
93 switch(eOption)
95 case SvtCTLOptions::E_CTLFONT : bReadOnly = m_bROCTLFontEnabled ; break;
96 case SvtCTLOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_bROCTLSequenceChecking ; break;
97 case SvtCTLOptions::E_CTLCURSORMOVEMENT : bReadOnly = m_bROCTLCursorMovement ; break;
98 case SvtCTLOptions::E_CTLTEXTNUMERALS : bReadOnly = m_bROCTLTextNumerals ; break;
99 case SvtCTLOptions::E_CTLSEQUENCECHECKINGRESTRICTED: bReadOnly = m_bROCTLRestricted ; break;
100 case SvtCTLOptions::E_CTLSEQUENCECHECKINGTYPEANDREPLACE: bReadOnly = m_bROCTLTypeAndReplace; break;
101 default: assert(false);
103 return bReadOnly;
105 SvtCTLOptions_Impl::SvtCTLOptions_Impl() :
107 utl::ConfigItem("Office.Common/I18N/CTL"),
109 m_bIsLoaded ( false ),
110 m_bCTLFontEnabled ( true ),
111 m_bCTLSequenceChecking ( false ),
112 m_bCTLRestricted ( false ),
113 m_bCTLTypeAndReplace ( false ),
114 m_eCTLCursorMovement ( SvtCTLOptions::MOVEMENT_LOGICAL ),
115 m_eCTLTextNumerals ( SvtCTLOptions::NUMERALS_ARABIC ),
117 m_bROCTLFontEnabled ( CFG_READONLY_DEFAULT ),
118 m_bROCTLSequenceChecking( CFG_READONLY_DEFAULT ),
119 m_bROCTLRestricted ( CFG_READONLY_DEFAULT ),
120 m_bROCTLTypeAndReplace ( CFG_READONLY_DEFAULT ),
121 m_bROCTLCursorMovement ( CFG_READONLY_DEFAULT ),
122 m_bROCTLTextNumerals ( CFG_READONLY_DEFAULT )
125 SvtCTLOptions_Impl::~SvtCTLOptions_Impl()
127 assert(!IsModified()); // should have been committed
130 void SvtCTLOptions_Impl::Notify( const Sequence< OUString >& )
132 Load();
133 NotifyListeners(ConfigurationHints::CtlSettingsChanged);
136 void SvtCTLOptions_Impl::ImplCommit()
138 Sequence< OUString > &rPropertyNames = PropertyNames::get();
139 OUString* pOrgNames = rPropertyNames.getArray();
140 sal_Int32 nOrgCount = rPropertyNames.getLength();
142 Sequence< OUString > aNames( nOrgCount );
143 Sequence< Any > aValues( nOrgCount );
145 OUString* pNames = aNames.getArray();
146 Any* pValues = aValues.getArray();
147 sal_Int32 nRealCount = 0;
149 for ( int nProp = 0; nProp < nOrgCount; nProp++ )
151 switch ( nProp )
153 case 0:
155 if (!m_bROCTLFontEnabled)
157 pNames[nRealCount] = pOrgNames[nProp];
158 pValues[nRealCount] <<= m_bCTLFontEnabled;
159 ++nRealCount;
162 break;
164 case 1:
166 if (!m_bROCTLSequenceChecking)
168 pNames[nRealCount] = pOrgNames[nProp];
169 pValues[nRealCount] <<= m_bCTLSequenceChecking;
170 ++nRealCount;
173 break;
175 case 2:
177 if (!m_bROCTLCursorMovement)
179 pNames[nRealCount] = pOrgNames[nProp];
180 pValues[nRealCount] <<= static_cast<sal_Int32>(m_eCTLCursorMovement);
181 ++nRealCount;
184 break;
186 case 3:
188 if (!m_bROCTLTextNumerals)
190 pNames[nRealCount] = pOrgNames[nProp];
191 pValues[nRealCount] <<= static_cast<sal_Int32>(m_eCTLTextNumerals);
192 ++nRealCount;
195 break;
197 case 4:
199 if (!m_bROCTLRestricted)
201 pNames[nRealCount] = pOrgNames[nProp];
202 pValues[nRealCount] <<= m_bCTLRestricted;
203 ++nRealCount;
206 break;
207 case 5:
209 if(!m_bROCTLTypeAndReplace)
211 pNames[nRealCount] = pOrgNames[nProp];
212 pValues[nRealCount] <<= m_bCTLTypeAndReplace;
213 ++nRealCount;
216 break;
219 aNames.realloc(nRealCount);
220 aValues.realloc(nRealCount);
221 PutProperties( aNames, aValues );
222 //broadcast changes
223 NotifyListeners(ConfigurationHints::CtlSettingsChanged);
226 void SvtCTLOptions_Impl::Load()
228 Sequence< OUString >& rPropertyNames = PropertyNames::get();
229 if ( !rPropertyNames.hasElements() )
231 rPropertyNames.realloc(6);
232 OUString* pNames = rPropertyNames.getArray();
233 pNames[0] = "CTLFont";
234 pNames[1] = "CTLSequenceChecking";
235 pNames[2] = "CTLCursorMovement";
236 pNames[3] = "CTLTextNumerals";
237 pNames[4] = "CTLSequenceCheckingRestricted";
238 pNames[5] = "CTLSequenceCheckingTypeAndReplace";
239 EnableNotification( rPropertyNames );
241 Sequence< Any > aValues = GetProperties( rPropertyNames );
242 Sequence< sal_Bool > aROStates = GetReadOnlyStates( rPropertyNames );
243 const Any* pValues = aValues.getConstArray();
244 const sal_Bool* pROStates = aROStates.getConstArray();
245 assert(aValues.getLength() == rPropertyNames.getLength() && "GetProperties failed");
246 assert(aROStates.getLength() == rPropertyNames.getLength() && "GetReadOnlyStates failed");
247 if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() )
249 bool bValue = false;
250 sal_Int32 nValue = 0;
252 for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
254 if ( pValues[nProp].hasValue() )
256 if ( pValues[nProp] >>= bValue )
258 switch ( nProp )
260 case 0: { m_bCTLFontEnabled = bValue; m_bROCTLFontEnabled = pROStates[nProp]; } break;
261 case 1: { m_bCTLSequenceChecking = bValue; m_bROCTLSequenceChecking = pROStates[nProp]; } break;
262 case 4: { m_bCTLRestricted = bValue; m_bROCTLRestricted = pROStates[nProp]; } break;
263 case 5: { m_bCTLTypeAndReplace = bValue; m_bROCTLTypeAndReplace = pROStates[nProp]; } break;
266 else if ( pValues[nProp] >>= nValue )
268 switch ( nProp )
270 case 2: { m_eCTLCursorMovement = static_cast<SvtCTLOptions::CursorMovement>(nValue); m_bROCTLCursorMovement = pROStates[nProp]; } break;
271 case 3: { m_eCTLTextNumerals = static_cast<SvtCTLOptions::TextNumerals>(nValue); m_bROCTLTextNumerals = pROStates[nProp]; } break;
278 m_bIsLoaded = true;
280 void SvtCTLOptions_Impl::SetCTLFontEnabled( bool _bEnabled )
282 if(!m_bROCTLFontEnabled && m_bCTLFontEnabled != _bEnabled)
284 m_bCTLFontEnabled = _bEnabled;
285 SetModified();
286 NotifyListeners(ConfigurationHints::NONE);
289 void SvtCTLOptions_Impl::SetCTLSequenceChecking( bool _bEnabled )
291 if(!m_bROCTLSequenceChecking && m_bCTLSequenceChecking != _bEnabled)
293 SetModified();
294 m_bCTLSequenceChecking = _bEnabled;
295 NotifyListeners(ConfigurationHints::NONE);
298 void SvtCTLOptions_Impl::SetCTLSequenceCheckingRestricted( bool _bEnabled )
300 if(!m_bROCTLRestricted && m_bCTLRestricted != _bEnabled)
302 SetModified();
303 m_bCTLRestricted = _bEnabled;
304 NotifyListeners(ConfigurationHints::NONE);
307 void SvtCTLOptions_Impl::SetCTLSequenceCheckingTypeAndReplace( bool _bEnabled )
309 if(!m_bROCTLTypeAndReplace && m_bCTLTypeAndReplace != _bEnabled)
311 SetModified();
312 m_bCTLTypeAndReplace = _bEnabled;
313 NotifyListeners(ConfigurationHints::NONE);
316 void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
318 if (!m_bROCTLCursorMovement && m_eCTLCursorMovement != _eMovement )
320 SetModified();
321 m_eCTLCursorMovement = _eMovement;
322 NotifyListeners(ConfigurationHints::NONE);
325 void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
327 if (!m_bROCTLTextNumerals && m_eCTLTextNumerals != _eNumerals )
329 SetModified();
330 m_eCTLTextNumerals = _eNumerals;
331 NotifyListeners(ConfigurationHints::NONE);
335 namespace {
337 // global
338 std::weak_ptr<SvtCTLOptions_Impl> g_pCTLOptions;
340 struct CTLMutex : public rtl::Static< osl::Mutex, CTLMutex > {};
343 SvtCTLOptions::SvtCTLOptions( bool bDontLoad )
345 // Global access, must be guarded (multithreading)
346 ::osl::MutexGuard aGuard( CTLMutex::get() );
348 m_pImpl = g_pCTLOptions.lock();
349 if ( !m_pImpl )
351 m_pImpl = std::make_shared<SvtCTLOptions_Impl>();
352 g_pCTLOptions = m_pImpl;
353 ItemHolder2::holdConfigItem(EItem::CTLOptions);
356 if( !bDontLoad && !m_pImpl->IsLoaded() )
357 m_pImpl->Load();
359 m_pImpl->AddListener(this);
363 SvtCTLOptions::~SvtCTLOptions()
365 // Global access, must be guarded (multithreading)
366 ::osl::MutexGuard aGuard( CTLMutex::get() );
368 m_pImpl->RemoveListener(this);
369 m_pImpl.reset();
372 void SvtCTLOptions::SetCTLFontEnabled( bool _bEnabled )
374 assert(m_pImpl->IsLoaded());
375 m_pImpl->SetCTLFontEnabled( _bEnabled );
378 bool SvtCTLOptions::IsCTLFontEnabled() const
380 assert(m_pImpl->IsLoaded());
381 return m_pImpl->IsCTLFontEnabled();
384 void SvtCTLOptions::SetCTLSequenceChecking( bool _bEnabled )
386 assert(m_pImpl->IsLoaded());
387 m_pImpl->SetCTLSequenceChecking(_bEnabled);
390 bool SvtCTLOptions::IsCTLSequenceChecking() const
392 assert(m_pImpl->IsLoaded());
393 return m_pImpl->IsCTLSequenceChecking();
396 void SvtCTLOptions::SetCTLSequenceCheckingRestricted( bool _bEnable )
398 assert(m_pImpl->IsLoaded());
399 m_pImpl->SetCTLSequenceCheckingRestricted(_bEnable);
402 bool SvtCTLOptions::IsCTLSequenceCheckingRestricted() const
404 assert(m_pImpl->IsLoaded());
405 return m_pImpl->IsCTLSequenceCheckingRestricted();
408 void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( bool _bEnable )
410 assert(m_pImpl->IsLoaded());
411 m_pImpl->SetCTLSequenceCheckingTypeAndReplace(_bEnable);
414 bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const
416 assert(m_pImpl->IsLoaded());
417 return m_pImpl->IsCTLSequenceCheckingTypeAndReplace();
420 void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
422 assert(m_pImpl->IsLoaded());
423 m_pImpl->SetCTLCursorMovement( _eMovement );
426 SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const
428 assert(m_pImpl->IsLoaded());
429 return m_pImpl->GetCTLCursorMovement();
432 void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
434 assert(m_pImpl->IsLoaded());
435 m_pImpl->SetCTLTextNumerals( _eNumerals );
438 SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const
440 assert(m_pImpl->IsLoaded());
441 return m_pImpl->GetCTLTextNumerals();
444 bool SvtCTLOptions::IsReadOnly(EOption eOption) const
446 assert(m_pImpl->IsLoaded());
447 return m_pImpl->IsReadOnly(eOption);
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */