Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / linguistic / source / lngopt.cxx
blobd46dfbb52bbd52b78615d1de34e87b5471bc6e5f
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 <sal/macros.h>
22 #include "lngopt.hxx"
23 #include <linguistic/misc.hxx>
24 #include <o3tl/safeint.hxx>
25 #include <tools/debug.hxx>
26 #include <unotools/lingucfg.hxx>
28 #include <comphelper/sequence.hxx>
29 #include <cppuhelper/factory.hxx>
30 #include <cppuhelper/supportsservice.hxx>
31 #include <cppuhelper/weak.hxx>
32 #include <com/sun/star/lang/Locale.hpp>
34 using namespace utl;
35 using namespace osl;
36 using namespace com::sun::star;
37 using namespace com::sun::star::beans;
38 using namespace com::sun::star::lang;
39 using namespace com::sun::star::uno;
40 using namespace com::sun::star::linguistic2;
41 using namespace linguistic;
43 using namespace com::sun::star::registry;
46 // static member initialization
47 SvtLinguOptions * LinguOptions::pData = nullptr;
48 oslInterlockedCount LinguOptions::nRefCount;
51 LinguOptions::LinguOptions()
53 if (!pData)
55 pData = new SvtLinguOptions;
56 SvtLinguConfig aLinguCfg;
57 aLinguCfg.GetOptions( *pData );
60 osl_atomic_increment( &nRefCount );
64 LinguOptions::LinguOptions(const LinguOptions & /*rOpt*/)
66 DBG_ASSERT( pData, "lng : data missing" );
67 osl_atomic_increment( &nRefCount );
71 LinguOptions::~LinguOptions()
73 MutexGuard aGuard( GetLinguMutex() );
75 if ( osl_atomic_decrement( &nRefCount ) == 0 )
77 delete pData; pData = nullptr;
81 namespace {
83 struct WID_Name
85 sal_Int32 nWID;
86 OUString aPropertyName;
91 //! order of entries is import (see LinguOptions::GetName)
92 //! since the WID is used as index in this table!
93 WID_Name const aWID_Name[] =
95 { 0, "" },
96 { UPH_IS_USE_DICTIONARY_LIST, UPN_IS_USE_DICTIONARY_LIST },
97 { UPH_IS_IGNORE_CONTROL_CHARACTERS, UPN_IS_IGNORE_CONTROL_CHARACTERS },
98 { UPH_IS_SPELL_UPPER_CASE, UPN_IS_SPELL_UPPER_CASE },
99 { UPH_IS_SPELL_WITH_DIGITS, UPN_IS_SPELL_WITH_DIGITS },
100 { UPH_IS_SPELL_CAPITALIZATION, UPN_IS_SPELL_CAPITALIZATION },
101 { UPH_HYPH_MIN_LEADING, UPN_HYPH_MIN_LEADING },
102 { UPH_HYPH_MIN_TRAILING, UPN_HYPH_MIN_TRAILING },
103 { UPH_HYPH_MIN_WORD_LENGTH, UPN_HYPH_MIN_WORD_LENGTH },
104 { UPH_DEFAULT_LOCALE, UPN_DEFAULT_LOCALE },
105 { UPH_IS_SPELL_AUTO, UPN_IS_SPELL_AUTO },
106 { 0, "" },
107 { 0, "" },
108 { UPH_IS_SPELL_SPECIAL, UPN_IS_SPELL_SPECIAL },
109 { UPH_IS_HYPH_AUTO, UPN_IS_HYPH_AUTO },
110 { UPH_IS_HYPH_SPECIAL, UPN_IS_HYPH_SPECIAL },
111 { UPH_IS_WRAP_REVERSE, UPN_IS_WRAP_REVERSE },
112 { 0, "" },
113 { 0, "" },
114 { 0, "" },
115 { 0, "" },
116 { UPH_DEFAULT_LANGUAGE, UPN_DEFAULT_LANGUAGE },
117 { UPH_DEFAULT_LOCALE_CJK, UPN_DEFAULT_LOCALE_CJK },
118 { UPH_DEFAULT_LOCALE_CTL, UPN_DEFAULT_LOCALE_CTL },
119 { UPH_IS_SPELL_CLOSED_COMPOUND, UPN_IS_SPELL_CLOSED_COMPOUND },
120 { UPH_IS_SPELL_HYPHENATED_COMPOUND, UPN_IS_SPELL_HYPHENATED_COMPOUND }
124 OUString LinguOptions::GetName( sal_Int32 nWID )
126 MutexGuard aGuard( GetLinguMutex() );
128 OUString aRes;
130 if (0 <= nWID && o3tl::make_unsigned(nWID) < SAL_N_ELEMENTS(aWID_Name)
131 && aWID_Name[ nWID ].nWID == nWID)
132 aRes = aWID_Name[nWID].aPropertyName;
133 else
134 OSL_FAIL("lng : unknown WID");
136 return aRes;
140 //! map must be sorted by first entry in alphabetical increasing order.
141 static o3tl::span<const SfxItemPropertyMapEntry> lcl_GetLinguProps()
143 static const SfxItemPropertyMapEntry aLinguProps[] =
145 { UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE,
146 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
147 { UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE,
148 ::cppu::UnoType<Locale>::get(), 0, 0 },
149 { UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK,
150 ::cppu::UnoType<Locale>::get(), 0, 0 },
151 { UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL,
152 ::cppu::UnoType<Locale>::get(), 0, 0 },
153 { UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING,
154 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
155 { UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING,
156 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
157 { UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH,
158 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
159 { UPN_IS_GERMAN_PRE_REFORM, UPH_IS_GERMAN_PRE_REFORM, /*! deprecated !*/
160 cppu::UnoType<bool>::get(), 0, 0 },
161 { UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO,
162 cppu::UnoType<bool>::get(), 0, 0 },
163 { UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL,
164 cppu::UnoType<bool>::get(), 0, 0 },
165 { UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS,
166 cppu::UnoType<bool>::get(), 0, 0 },
167 { UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO,
168 cppu::UnoType<bool>::get(), 0, 0 },
169 { UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION,
170 cppu::UnoType<bool>::get(), 0, 0 },
171 { UPN_IS_SPELL_CLOSED_COMPOUND, UPH_IS_SPELL_CLOSED_COMPOUND,
172 cppu::UnoType<bool>::get(), 0, 0 },
173 { UPN_IS_SPELL_HYPHENATED_COMPOUND, UPH_IS_SPELL_HYPHENATED_COMPOUND,
174 cppu::UnoType<bool>::get(), 0, 0 },
175 { UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL,
176 cppu::UnoType<bool>::get(), 0, 0 },
177 { UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE,
178 cppu::UnoType<bool>::get(), 0, 0 },
179 { UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS,
180 cppu::UnoType<bool>::get(), 0, 0 },
181 { UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST,
182 cppu::UnoType<bool>::get(), 0, 0 },
183 { UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE,
184 cppu::UnoType<bool>::get(), 0, 0 },
186 return aLinguProps;
188 LinguProps::LinguProps() :
189 aEvtListeners (GetLinguMutex()),
190 aPropListeners (GetLinguMutex()),
191 aPropertyMap(lcl_GetLinguProps())
193 bDisposing = false;
196 void LinguProps::launchEvent( const PropertyChangeEvent &rEvt ) const
198 comphelper::OInterfaceContainerHelper3<XPropertyChangeListener> *pContainer =
199 aPropListeners.getContainer( rEvt.PropertyHandle );
200 if (pContainer)
201 pContainer->notifyEach( &XPropertyChangeListener::propertyChange, rEvt );
204 Reference< XPropertySetInfo > SAL_CALL LinguProps::getPropertySetInfo()
206 MutexGuard aGuard( GetLinguMutex() );
208 static Reference< XPropertySetInfo > aRef =
209 new SfxItemPropertySetInfo( aPropertyMap );
210 return aRef;
213 void SAL_CALL LinguProps::setPropertyValue(
214 const OUString& rPropertyName, const Any& rValue )
216 MutexGuard aGuard( GetLinguMutex() );
218 const SfxItemPropertyMapEntry* pCur = aPropertyMap.getByName( rPropertyName );
219 if (pCur)
221 Any aOld( aConfig.GetProperty( pCur->nWID ) );
222 if (aOld != rValue && aConfig.SetProperty( pCur->nWID, rValue ))
224 PropertyChangeEvent aChgEvt( static_cast<XPropertySet *>(this), rPropertyName,
225 false, pCur->nWID, aOld, rValue );
226 launchEvent( aChgEvt );
231 Any SAL_CALL LinguProps::getPropertyValue( const OUString& rPropertyName )
233 MutexGuard aGuard( GetLinguMutex() );
235 Any aRet;
237 const SfxItemPropertyMapEntry* pCur = aPropertyMap.getByName( rPropertyName );
238 if(pCur)
240 aRet = aConfig.GetProperty( pCur->nWID );
243 return aRet;
246 void SAL_CALL LinguProps::addPropertyChangeListener(
247 const OUString& rPropertyName,
248 const Reference< XPropertyChangeListener >& rxListener )
250 MutexGuard aGuard( GetLinguMutex() );
252 if (!bDisposing && rxListener.is())
254 const SfxItemPropertyMapEntry* pCur = aPropertyMap.getByName( rPropertyName );
255 if(pCur)
256 aPropListeners.addInterface( pCur->nWID, rxListener );
260 void SAL_CALL LinguProps::removePropertyChangeListener(
261 const OUString& rPropertyName,
262 const Reference< XPropertyChangeListener >& rxListener )
264 MutexGuard aGuard( GetLinguMutex() );
266 if (!bDisposing && rxListener.is())
268 const SfxItemPropertyMapEntry* pCur = aPropertyMap.getByName( rPropertyName );
269 if(pCur)
270 aPropListeners.removeInterface( pCur->nWID, rxListener );
274 void SAL_CALL LinguProps::addVetoableChangeListener(
275 const OUString& /*rPropertyName*/,
276 const Reference< XVetoableChangeListener >& /*xListener*/ )
280 void SAL_CALL LinguProps::removeVetoableChangeListener(
281 const OUString& /*rPropertyName*/,
282 const Reference< XVetoableChangeListener >& /*xListener*/ )
287 void SAL_CALL LinguProps::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
289 MutexGuard aGuard( GetLinguMutex() );
291 Any aOld( aConfig.GetProperty( nHandle ) );
292 if (aOld != rValue && aConfig.SetProperty( nHandle, rValue ))
294 PropertyChangeEvent aChgEvt( static_cast<XPropertySet *>(this),
295 LinguOptions::GetName( nHandle ), false, nHandle, aOld, rValue );
296 launchEvent( aChgEvt );
301 Any SAL_CALL LinguProps::getFastPropertyValue( sal_Int32 nHandle )
303 MutexGuard aGuard( GetLinguMutex() );
305 Any aRes( aConfig.GetProperty( nHandle ) );
306 return aRes;
310 Sequence< PropertyValue > SAL_CALL
311 LinguProps::getPropertyValues()
313 MutexGuard aGuard( GetLinguMutex() );
315 std::vector<PropertyValue> aProps;
316 aProps.reserve(aPropertyMap.getPropertyEntries().size());
317 for(auto pEntry : aPropertyMap.getPropertyEntries())
318 aProps.push_back(PropertyValue(pEntry->aName, pEntry->nWID,
319 aConfig.GetProperty(pEntry->nWID),
320 css::beans::PropertyState_DIRECT_VALUE));
321 return comphelper::containerToSequence(aProps);
324 void SAL_CALL
325 LinguProps::setPropertyValues( const Sequence< PropertyValue >& rProps )
327 MutexGuard aGuard( GetLinguMutex() );
329 for (const PropertyValue &rVal : rProps)
331 setPropertyValue( rVal.Name, rVal.Value );
335 void SAL_CALL
336 LinguProps::dispose()
338 MutexGuard aGuard( GetLinguMutex() );
340 if (!bDisposing)
342 bDisposing = true;
344 //! it's too late to save the options here!
345 // (see AppExitListener for saving)
346 //aOpt.Save(); // save (possible) changes before exiting
348 EventObject aEvtObj( static_cast<XPropertySet *>(this) );
349 aEvtListeners.disposeAndClear( aEvtObj );
350 aPropListeners.disposeAndClear( aEvtObj );
354 void SAL_CALL
355 LinguProps::addEventListener( const Reference< XEventListener >& rxListener )
357 MutexGuard aGuard( GetLinguMutex() );
359 if (!bDisposing && rxListener.is())
360 aEvtListeners.addInterface( rxListener );
363 void SAL_CALL
364 LinguProps::removeEventListener( const Reference< XEventListener >& rxListener )
366 MutexGuard aGuard( GetLinguMutex() );
368 if (!bDisposing && rxListener.is())
369 aEvtListeners.removeInterface( rxListener );
373 // Service specific part
375 // XServiceInfo
376 OUString SAL_CALL LinguProps::getImplementationName()
378 return "com.sun.star.lingu2.LinguProps";
381 // XServiceInfo
382 sal_Bool SAL_CALL LinguProps::supportsService( const OUString& ServiceName )
384 return cppu::supportsService(this, ServiceName);
387 // XServiceInfo
388 uno::Sequence< OUString > SAL_CALL LinguProps::getSupportedServiceNames()
390 return { "com.sun.star.linguistic2.LinguProperties" };
393 bool LinguProps::getPropertyBool(const OUString& aPropertyName)
395 uno::Any any = getPropertyValue(aPropertyName);
396 bool b = false;
397 any >>= b;
398 return b;
401 sal_Int16 LinguProps::getPropertyInt16(const OUString& aPropertyName)
403 uno::Any any = getPropertyValue(aPropertyName);
404 sal_Int16 b = 0;
405 any >>= b;
406 return b;
409 Locale LinguProps::getPropertyLocale(const OUString& aPropertyName)
411 uno::Any any = getPropertyValue(aPropertyName);
412 css::lang::Locale b;
413 any >>= b;
414 return b;
417 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
418 linguistic_LinguProps_get_implementation(
419 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
421 return cppu::acquire(new LinguProps());
425 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */