bump product version to 4.1.6.2
[LibreOffice.git] / linguistic / source / lngopt.cxx
blob75babc93dfceac619e57b06ffe027ab2ea9a6369
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/lngprops.hxx"
24 #include "linguistic/misc.hxx"
25 #include <tools/debug.hxx>
26 #include <unotools/lingucfg.hxx>
28 #include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
29 #include <cppuhelper/implbase1.hxx> // helper for implementations
31 #include <cppuhelper/factory.hxx> // helper for factories
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/registry/XSimpleRegistry.hpp>
34 #include <com/sun/star/registry/XRegistryKey.hpp>
35 #include <com/sun/star/lang/Locale.hpp>
36 #include <com/sun/star/i18n/ScriptType.hpp>
37 #include <i18nlangtag/mslangid.hxx>
39 using namespace utl;
40 using namespace osl;
41 using namespace com::sun::star;
42 using namespace com::sun::star::container;
43 using namespace com::sun::star::beans;
44 using namespace com::sun::star::lang;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::linguistic2;
47 using namespace linguistic;
49 using namespace com::sun::star::registry;
54 // static member intialization
55 SvtLinguOptions * LinguOptions::pData = NULL;
56 oslInterlockedCount LinguOptions::nRefCount;
59 LinguOptions::LinguOptions()
61 if (!pData)
63 pData = new SvtLinguOptions;
64 SvtLinguConfig aLinguCfg;
65 aLinguCfg.GetOptions( *pData );
68 osl_atomic_increment( &nRefCount );
72 LinguOptions::LinguOptions(const LinguOptions & /*rOpt*/)
74 DBG_ASSERT( pData, "lng : data missing" );
75 osl_atomic_increment( &nRefCount );
79 LinguOptions::~LinguOptions()
81 MutexGuard aGuard( GetLinguMutex() );
83 if ( osl_atomic_decrement( &nRefCount ) == 0 )
85 delete pData; pData = NULL;
89 struct WID_Name
91 sal_Int32 nWID;
92 const char *pPropertyName;
95 //! order of entries is import (see LinguOptions::GetName)
96 //! since the WID is used as index in this table!
97 WID_Name aWID_Name[] =
99 { 0, 0 },
100 { WID_IS_USE_DICTIONARY_LIST, UPN_IS_USE_DICTIONARY_LIST },
101 { WID_IS_IGNORE_CONTROL_CHARACTERS, UPN_IS_IGNORE_CONTROL_CHARACTERS },
102 { WID_IS_SPELL_UPPER_CASE, UPN_IS_SPELL_UPPER_CASE },
103 { WID_IS_SPELL_WITH_DIGITS, UPN_IS_SPELL_WITH_DIGITS },
104 { WID_IS_SPELL_CAPITALIZATION, UPN_IS_SPELL_CAPITALIZATION },
105 { WID_HYPH_MIN_LEADING, UPN_HYPH_MIN_LEADING },
106 { WID_HYPH_MIN_TRAILING, UPN_HYPH_MIN_TRAILING },
107 { WID_HYPH_MIN_WORD_LENGTH, UPN_HYPH_MIN_WORD_LENGTH },
108 { WID_DEFAULT_LOCALE, UPN_DEFAULT_LOCALE },
109 { WID_IS_SPELL_AUTO, UPN_IS_SPELL_AUTO },
110 { 0, 0 },
111 { 0, 0 },
112 { WID_IS_SPELL_SPECIAL, UPN_IS_SPELL_SPECIAL },
113 { WID_IS_HYPH_AUTO, UPN_IS_HYPH_AUTO },
114 { WID_IS_HYPH_SPECIAL, UPN_IS_HYPH_SPECIAL },
115 { WID_IS_WRAP_REVERSE, UPN_IS_WRAP_REVERSE },
116 { 0, 0 },
117 { 0, 0 },
118 { 0, 0 },
119 { 0, 0 },
120 { WID_DEFAULT_LANGUAGE, UPN_DEFAULT_LANGUAGE },
121 { WID_DEFAULT_LOCALE_CJK, UPN_DEFAULT_LOCALE_CJK },
122 { WID_DEFAULT_LOCALE_CTL, UPN_DEFAULT_LOCALE_CTL }
126 OUString LinguOptions::GetName( sal_Int32 nWID )
128 MutexGuard aGuard( GetLinguMutex() );
130 OUString aRes;
132 sal_Int32 nLen = sizeof (aWID_Name) / sizeof (aWID_Name[0]);
133 if (0 <= nWID && nWID < nLen && aWID_Name[ nWID ].nWID == nWID)
134 aRes = OUString::createFromAscii(aWID_Name[nWID].pPropertyName);
135 else
136 OSL_FAIL("lng : unknown WID");
138 return aRes;
143 //! map must be sorted by first entry in alphabetical increasing order.
144 static const SfxItemPropertyMapEntry* lcl_GetLinguProps()
146 static const SfxItemPropertyMapEntry aLinguProps[] =
148 { MAP_CHAR_LEN(UPN_DEFAULT_LANGUAGE), WID_DEFAULT_LANGUAGE,
149 &::getCppuType( (sal_Int16*)0 ), 0, 0 },
150 { MAP_CHAR_LEN(UPN_DEFAULT_LOCALE), WID_DEFAULT_LOCALE,
151 &::getCppuType( (Locale* )0), 0, 0 },
152 { MAP_CHAR_LEN(UPN_DEFAULT_LOCALE_CJK), WID_DEFAULT_LOCALE_CJK,
153 &::getCppuType( (Locale* )0), 0, 0 },
154 { MAP_CHAR_LEN(UPN_DEFAULT_LOCALE_CTL), WID_DEFAULT_LOCALE_CTL,
155 &::getCppuType( (Locale* )0), 0, 0 },
156 { MAP_CHAR_LEN(UPN_HYPH_MIN_LEADING), WID_HYPH_MIN_LEADING,
157 &::getCppuType( (sal_Int16*)0 ), 0, 0 },
158 { MAP_CHAR_LEN(UPN_HYPH_MIN_TRAILING), WID_HYPH_MIN_TRAILING,
159 &::getCppuType( (sal_Int16*)0 ), 0, 0 },
160 { MAP_CHAR_LEN(UPN_HYPH_MIN_WORD_LENGTH), WID_HYPH_MIN_WORD_LENGTH,
161 &::getCppuType( (sal_Int16*)0 ), 0, 0 },
162 { MAP_CHAR_LEN(UPN_IS_GERMAN_PRE_REFORM), WID_IS_GERMAN_PRE_REFORM, /*! deprecated !*/
163 &::getBooleanCppuType(), 0, 0 },
164 { MAP_CHAR_LEN(UPN_IS_HYPH_AUTO), WID_IS_HYPH_AUTO,
165 &::getBooleanCppuType(), 0, 0 },
166 { MAP_CHAR_LEN(UPN_IS_HYPH_SPECIAL), WID_IS_HYPH_SPECIAL,
167 &::getBooleanCppuType(), 0, 0 },
168 { MAP_CHAR_LEN(UPN_IS_IGNORE_CONTROL_CHARACTERS), WID_IS_IGNORE_CONTROL_CHARACTERS,
169 &::getBooleanCppuType(), 0, 0 },
170 { MAP_CHAR_LEN(UPN_IS_SPELL_AUTO), WID_IS_SPELL_AUTO,
171 &::getBooleanCppuType(), 0, 0 },
172 { MAP_CHAR_LEN(UPN_IS_SPELL_CAPITALIZATION), WID_IS_SPELL_CAPITALIZATION,
173 &::getBooleanCppuType(), 0, 0 },
174 { MAP_CHAR_LEN(UPN_IS_SPELL_HIDE), WID_IS_SPELL_HIDE, /*! deprecated !*/
175 &::getBooleanCppuType(), 0, 0 },
176 { MAP_CHAR_LEN(UPN_IS_SPELL_IN_ALL_LANGUAGES), WID_IS_SPELL_IN_ALL_LANGUAGES, /*! deprecated !*/
177 &::getBooleanCppuType(), 0, 0 },
178 { MAP_CHAR_LEN(UPN_IS_SPELL_SPECIAL), WID_IS_SPELL_SPECIAL,
179 &::getBooleanCppuType(), 0, 0 },
180 { MAP_CHAR_LEN(UPN_IS_SPELL_UPPER_CASE), WID_IS_SPELL_UPPER_CASE,
181 &::getBooleanCppuType(), 0, 0 },
182 { MAP_CHAR_LEN(UPN_IS_SPELL_WITH_DIGITS), WID_IS_SPELL_WITH_DIGITS,
183 &::getBooleanCppuType(), 0, 0 },
184 { MAP_CHAR_LEN(UPN_IS_USE_DICTIONARY_LIST), WID_IS_USE_DICTIONARY_LIST,
185 &::getBooleanCppuType(), 0, 0 },
186 { MAP_CHAR_LEN(UPN_IS_WRAP_REVERSE), WID_IS_WRAP_REVERSE,
187 &::getBooleanCppuType(), 0, 0 },
188 { 0,0,0,0,0,0 }
190 return aLinguProps;
192 LinguProps::LinguProps() :
193 aEvtListeners (GetLinguMutex()),
194 aPropListeners (GetLinguMutex()),
195 aPropertyMap(lcl_GetLinguProps())
197 bDisposing = sal_False;
200 void LinguProps::launchEvent( const PropertyChangeEvent &rEvt ) const
202 cppu::OInterfaceContainerHelper *pContainer =
203 aPropListeners.getContainer( rEvt.PropertyHandle );
204 if (pContainer)
206 cppu::OInterfaceIteratorHelper aIt( *pContainer );
207 while (aIt.hasMoreElements())
209 Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY );
210 if (xRef.is())
211 xRef->propertyChange( rEvt );
216 Reference< XInterface > SAL_CALL LinguProps_CreateInstance(
217 const Reference< XMultiServiceFactory > & /*rSMgr*/ )
218 throw(Exception)
220 Reference< XInterface > xService = (cppu::OWeakObject*)new LinguProps;
221 return xService;
224 Reference< XPropertySetInfo > SAL_CALL LinguProps::getPropertySetInfo()
225 throw(RuntimeException)
227 MutexGuard aGuard( GetLinguMutex() );
229 static Reference< XPropertySetInfo > aRef =
230 new SfxItemPropertySetInfo( aPropertyMap );
231 return aRef;
234 void SAL_CALL LinguProps::setPropertyValue(
235 const OUString& rPropertyName, const Any& rValue )
236 throw(UnknownPropertyException, PropertyVetoException,
237 IllegalArgumentException, WrappedTargetException, RuntimeException)
239 MutexGuard aGuard( GetLinguMutex() );
241 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
242 if (pCur)
244 Any aOld( aConfig.GetProperty( pCur->nWID ) );
245 if (aOld != rValue && aConfig.SetProperty( pCur->nWID, rValue ))
247 PropertyChangeEvent aChgEvt( (XPropertySet *) this, rPropertyName,
248 sal_False, pCur->nWID, aOld, rValue );
249 launchEvent( aChgEvt );
254 Any SAL_CALL LinguProps::getPropertyValue( const OUString& rPropertyName )
255 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
257 MutexGuard aGuard( GetLinguMutex() );
259 Any aRet;
261 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
262 if(pCur)
264 aRet = aConfig.GetProperty( pCur->nWID );
267 return aRet;
270 void SAL_CALL LinguProps::addPropertyChangeListener(
271 const OUString& rPropertyName,
272 const Reference< XPropertyChangeListener >& rxListener )
273 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
275 MutexGuard aGuard( GetLinguMutex() );
277 if (!bDisposing && rxListener.is())
279 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
280 if(pCur)
281 aPropListeners.addInterface( pCur->nWID, rxListener );
285 void SAL_CALL LinguProps::removePropertyChangeListener(
286 const OUString& rPropertyName,
287 const Reference< XPropertyChangeListener >& rxListener )
288 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
290 MutexGuard aGuard( GetLinguMutex() );
292 if (!bDisposing && rxListener.is())
294 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
295 if(pCur)
296 aPropListeners.removeInterface( pCur->nWID, rxListener );
300 void SAL_CALL LinguProps::addVetoableChangeListener(
301 const OUString& /*rPropertyName*/,
302 const Reference< XVetoableChangeListener >& /*xListener*/ )
303 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
307 void SAL_CALL LinguProps::removeVetoableChangeListener(
308 const OUString& /*rPropertyName*/,
309 const Reference< XVetoableChangeListener >& /*xListener*/ )
310 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
315 void SAL_CALL LinguProps::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
316 throw(UnknownPropertyException, PropertyVetoException,
317 IllegalArgumentException, WrappedTargetException, RuntimeException)
319 MutexGuard aGuard( GetLinguMutex() );
321 Any aOld( aConfig.GetProperty( nHandle ) );
322 if (aOld != rValue && aConfig.SetProperty( nHandle, rValue ))
324 PropertyChangeEvent aChgEvt( (XPropertySet *) this,
325 LinguOptions::GetName( nHandle ), sal_False, nHandle, aOld, rValue );
326 launchEvent( aChgEvt );
331 Any SAL_CALL LinguProps::getFastPropertyValue( sal_Int32 nHandle )
332 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
334 MutexGuard aGuard( GetLinguMutex() );
336 Any aRes( aConfig.GetProperty( nHandle ) );
337 return aRes;
341 Sequence< PropertyValue > SAL_CALL
342 LinguProps::getPropertyValues()
343 throw(RuntimeException)
345 MutexGuard aGuard( GetLinguMutex() );
347 sal_Int32 nLen = aPropertyMap.getSize();
348 Sequence< PropertyValue > aProps( nLen );
349 PropertyValue *pProp = aProps.getArray();
350 PropertyEntryVector_t aPropEntries = aPropertyMap.getPropertyEntries();
351 PropertyEntryVector_t::const_iterator aIt = aPropEntries.begin();
352 for (sal_Int32 i = 0; i < nLen; ++i, ++aIt)
354 PropertyValue &rVal = pProp[i];
355 Any aAny( aConfig.GetProperty( aIt->nWID ) );
357 rVal.Name = aIt->sName;
358 rVal.Handle = aIt->nWID;
359 rVal.Value = aAny;
360 rVal.State = PropertyState_DIRECT_VALUE ;
362 return aProps;
365 void SAL_CALL
366 LinguProps::setPropertyValues( const Sequence< PropertyValue >& rProps )
367 throw(UnknownPropertyException, PropertyVetoException,
368 IllegalArgumentException, WrappedTargetException, RuntimeException)
370 MutexGuard aGuard( GetLinguMutex() );
372 sal_Int32 nLen = rProps.getLength();
373 const PropertyValue *pVal = rProps.getConstArray();
374 for (sal_Int32 i = 0; i < nLen; ++i)
376 const PropertyValue &rVal = pVal[i];
377 setPropertyValue( rVal.Name, rVal.Value );
381 void SAL_CALL
382 LinguProps::dispose()
383 throw(RuntimeException)
385 MutexGuard aGuard( GetLinguMutex() );
387 if (!bDisposing)
389 bDisposing = sal_True;
391 //! its too late to save the options here!
392 // (see AppExitListener for saving)
393 //aOpt.Save(); // save (possible) changes before exiting
395 EventObject aEvtObj( (XPropertySet *) this );
396 aEvtListeners.disposeAndClear( aEvtObj );
397 aPropListeners.disposeAndClear( aEvtObj );
401 void SAL_CALL
402 LinguProps::addEventListener( const Reference< XEventListener >& rxListener )
403 throw(RuntimeException)
405 MutexGuard aGuard( GetLinguMutex() );
407 if (!bDisposing && rxListener.is())
408 aEvtListeners.addInterface( rxListener );
411 void SAL_CALL
412 LinguProps::removeEventListener( const Reference< XEventListener >& rxListener )
413 throw(RuntimeException)
415 MutexGuard aGuard( GetLinguMutex() );
417 if (!bDisposing && rxListener.is())
418 aEvtListeners.removeInterface( rxListener );
422 // Service specific part
424 // XServiceInfo
425 OUString SAL_CALL LinguProps::getImplementationName()
426 throw(RuntimeException)
428 MutexGuard aGuard( GetLinguMutex() );
429 return getImplementationName_Static();
432 // XServiceInfo
433 sal_Bool SAL_CALL LinguProps::supportsService( const OUString& ServiceName )
434 throw(RuntimeException)
436 MutexGuard aGuard( GetLinguMutex() );
438 uno::Sequence< OUString > aSNL = getSupportedServiceNames();
439 const OUString * pArray = aSNL.getConstArray();
440 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
441 if( pArray[i] == ServiceName )
442 return sal_True;
443 return sal_False;
446 // XServiceInfo
447 uno::Sequence< OUString > SAL_CALL LinguProps::getSupportedServiceNames()
448 throw(RuntimeException)
450 MutexGuard aGuard( GetLinguMutex() );
451 return getSupportedServiceNames_Static();
454 // ORegistryServiceManager_Static
455 uno::Sequence< OUString > LinguProps::getSupportedServiceNames_Static()
456 throw()
458 MutexGuard aGuard( GetLinguMutex() );
460 uno::Sequence< OUString > aSNS( 1 ); // more than 1 service possible
461 aSNS.getArray()[0] = "com.sun.star.linguistic2.LinguProperties";
462 return aSNS;
465 sal_Bool LinguProps::getPropertyBool(const OUString& aPropertyName) throw (css::uno::RuntimeException)
467 uno::Any any = getPropertyValue(aPropertyName);
468 sal_Bool b = sal_False;
469 any >>= b;
470 return b;
473 sal_Int16 LinguProps::getPropertyInt16(const OUString& aPropertyName) throw (css::uno::RuntimeException)
475 uno::Any any = getPropertyValue(aPropertyName);
476 sal_Int16 b = sal_False;
477 any >>= b;
478 return b;
481 Locale LinguProps::getPropertyLocale(const OUString& aPropertyName) throw (css::uno::RuntimeException)
483 uno::Any any = getPropertyValue(aPropertyName);
484 css::lang::Locale b;
485 any >>= b;
486 return b;
489 void * SAL_CALL LinguProps_getFactory( const sal_Char * pImplName,
490 XMultiServiceFactory *pServiceManager, void * )
492 void * pRet = 0;
493 if ( !LinguProps::getImplementationName_Static().compareToAscii( pImplName ) )
495 Reference< XSingleServiceFactory > xFactory =
496 cppu::createOneInstanceFactory(
497 pServiceManager,
498 LinguProps::getImplementationName_Static(),
499 LinguProps_CreateInstance,
500 LinguProps::getSupportedServiceNames_Static());
501 // acquire, because we return an interface pointer instead of a reference
502 xFactory->acquire();
503 pRet = xFactory.get();
505 return pRet;
509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */