tdf#121561 sw DOCX: output toc-end inside last toc paragraph
[LibreOffice.git] / linguistic / source / lngopt.cxx
blobcf89b437f98ce4d71ca7f19b0141b00d6f3a15fe
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 "lngreg.hxx"
24 #include <linguistic/lngprops.hxx>
25 #include <linguistic/misc.hxx>
26 #include <tools/debug.hxx>
27 #include <unotools/lingucfg.hxx>
29 #include <cppuhelper/factory.hxx>
30 #include <cppuhelper/supportsservice.hxx>
31 #include <com/sun/star/container/XNameAccess.hpp>
32 #include <com/sun/star/registry/XSimpleRegistry.hpp>
33 #include <com/sun/star/registry/XRegistryKey.hpp>
34 #include <com/sun/star/lang/Locale.hpp>
35 #include <com/sun/star/lang/XSingleServiceFactory.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;
52 // static member initialization
53 SvtLinguOptions * LinguOptions::pData = nullptr;
54 oslInterlockedCount LinguOptions::nRefCount;
57 LinguOptions::LinguOptions()
59 if (!pData)
61 pData = new SvtLinguOptions;
62 SvtLinguConfig aLinguCfg;
63 aLinguCfg.GetOptions( *pData );
66 osl_atomic_increment( &nRefCount );
70 LinguOptions::LinguOptions(const LinguOptions & /*rOpt*/)
72 DBG_ASSERT( pData, "lng : data missing" );
73 osl_atomic_increment( &nRefCount );
77 LinguOptions::~LinguOptions()
79 MutexGuard aGuard( GetLinguMutex() );
81 if ( osl_atomic_decrement( &nRefCount ) == 0 )
83 delete pData; pData = nullptr;
87 struct WID_Name
89 sal_Int32 nWID;
90 const char *pPropertyName;
93 //! order of entries is import (see LinguOptions::GetName)
94 //! since the WID is used as index in this table!
95 WID_Name const aWID_Name[] =
97 { 0, nullptr },
98 { UPH_IS_USE_DICTIONARY_LIST, UPN_IS_USE_DICTIONARY_LIST },
99 { UPH_IS_IGNORE_CONTROL_CHARACTERS, UPN_IS_IGNORE_CONTROL_CHARACTERS },
100 { UPH_IS_SPELL_UPPER_CASE, UPN_IS_SPELL_UPPER_CASE },
101 { UPH_IS_SPELL_WITH_DIGITS, UPN_IS_SPELL_WITH_DIGITS },
102 { UPH_IS_SPELL_CAPITALIZATION, UPN_IS_SPELL_CAPITALIZATION },
103 { UPH_HYPH_MIN_LEADING, UPN_HYPH_MIN_LEADING },
104 { UPH_HYPH_MIN_TRAILING, UPN_HYPH_MIN_TRAILING },
105 { UPH_HYPH_MIN_WORD_LENGTH, UPN_HYPH_MIN_WORD_LENGTH },
106 { UPH_DEFAULT_LOCALE, UPN_DEFAULT_LOCALE },
107 { UPH_IS_SPELL_AUTO, UPN_IS_SPELL_AUTO },
108 { 0, nullptr },
109 { 0, nullptr },
110 { UPH_IS_SPELL_SPECIAL, UPN_IS_SPELL_SPECIAL },
111 { UPH_IS_HYPH_AUTO, UPN_IS_HYPH_AUTO },
112 { UPH_IS_HYPH_SPECIAL, UPN_IS_HYPH_SPECIAL },
113 { UPH_IS_WRAP_REVERSE, UPN_IS_WRAP_REVERSE },
114 { 0, nullptr },
115 { 0, nullptr },
116 { 0, nullptr },
117 { 0, nullptr },
118 { UPH_DEFAULT_LANGUAGE, UPN_DEFAULT_LANGUAGE },
119 { UPH_DEFAULT_LOCALE_CJK, UPN_DEFAULT_LOCALE_CJK },
120 { UPH_DEFAULT_LOCALE_CTL, UPN_DEFAULT_LOCALE_CTL }
124 OUString LinguOptions::GetName( sal_Int32 nWID )
126 MutexGuard aGuard( GetLinguMutex() );
128 OUString aRes;
130 if (0 <= nWID && nWID < sal_Int32(SAL_N_ELEMENTS(aWID_Name)) && aWID_Name[ nWID ].nWID == nWID)
131 aRes = OUString::createFromAscii(aWID_Name[nWID].pPropertyName);
132 else
133 OSL_FAIL("lng : unknown WID");
135 return aRes;
139 //! map must be sorted by first entry in alphabetical increasing order.
140 static const SfxItemPropertyMapEntry* lcl_GetLinguProps()
142 static const SfxItemPropertyMapEntry aLinguProps[] =
144 { OUString(UPN_DEFAULT_LANGUAGE), UPH_DEFAULT_LANGUAGE,
145 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
146 { OUString(UPN_DEFAULT_LOCALE), UPH_DEFAULT_LOCALE,
147 ::cppu::UnoType<Locale>::get(), 0, 0 },
148 { OUString(UPN_DEFAULT_LOCALE_CJK), UPH_DEFAULT_LOCALE_CJK,
149 ::cppu::UnoType<Locale>::get(), 0, 0 },
150 { OUString(UPN_DEFAULT_LOCALE_CTL), UPH_DEFAULT_LOCALE_CTL,
151 ::cppu::UnoType<Locale>::get(), 0, 0 },
152 { OUString(UPN_HYPH_MIN_LEADING), UPH_HYPH_MIN_LEADING,
153 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
154 { OUString(UPN_HYPH_MIN_TRAILING), UPH_HYPH_MIN_TRAILING,
155 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
156 { OUString(UPN_HYPH_MIN_WORD_LENGTH), UPH_HYPH_MIN_WORD_LENGTH,
157 ::cppu::UnoType<sal_Int16>::get(), 0, 0 },
158 { OUString(UPN_IS_GERMAN_PRE_REFORM), UPH_IS_GERMAN_PRE_REFORM, /*! deprecated !*/
159 cppu::UnoType<bool>::get(), 0, 0 },
160 { OUString(UPN_IS_HYPH_AUTO), UPH_IS_HYPH_AUTO,
161 cppu::UnoType<bool>::get(), 0, 0 },
162 { OUString(UPN_IS_HYPH_SPECIAL), UPH_IS_HYPH_SPECIAL,
163 cppu::UnoType<bool>::get(), 0, 0 },
164 { OUString(UPN_IS_IGNORE_CONTROL_CHARACTERS), UPH_IS_IGNORE_CONTROL_CHARACTERS,
165 cppu::UnoType<bool>::get(), 0, 0 },
166 { OUString(UPN_IS_SPELL_AUTO), UPH_IS_SPELL_AUTO,
167 cppu::UnoType<bool>::get(), 0, 0 },
168 { OUString(UPN_IS_SPELL_CAPITALIZATION), UPH_IS_SPELL_CAPITALIZATION,
169 cppu::UnoType<bool>::get(), 0, 0 },
170 { OUString(UPN_IS_SPELL_HIDE), UPH_IS_SPELL_HIDE, /*! deprecated !*/
171 cppu::UnoType<bool>::get(), 0, 0 },
172 { OUString(UPN_IS_SPELL_IN_ALL_LANGUAGES), UPH_IS_SPELL_IN_ALL_LANGUAGES, /*! deprecated !*/
173 cppu::UnoType<bool>::get(), 0, 0 },
174 { OUString(UPN_IS_SPELL_SPECIAL), UPH_IS_SPELL_SPECIAL,
175 cppu::UnoType<bool>::get(), 0, 0 },
176 { OUString(UPN_IS_SPELL_UPPER_CASE), UPH_IS_SPELL_UPPER_CASE,
177 cppu::UnoType<bool>::get(), 0, 0 },
178 { OUString(UPN_IS_SPELL_WITH_DIGITS), UPH_IS_SPELL_WITH_DIGITS,
179 cppu::UnoType<bool>::get(), 0, 0 },
180 { OUString(UPN_IS_USE_DICTIONARY_LIST), UPH_IS_USE_DICTIONARY_LIST,
181 cppu::UnoType<bool>::get(), 0, 0 },
182 { OUString(UPN_IS_WRAP_REVERSE), UPH_IS_WRAP_REVERSE,
183 cppu::UnoType<bool>::get(), 0, 0 },
184 { OUString(), 0, css::uno::Type(), 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 cppu::OInterfaceContainerHelper *pContainer =
199 aPropListeners.getContainer( rEvt.PropertyHandle );
200 if (pContainer)
202 cppu::OInterfaceIteratorHelper aIt( *pContainer );
203 while (aIt.hasMoreElements())
205 Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY );
206 if (xRef.is())
207 xRef->propertyChange( rEvt );
212 /// @throws Exception
213 static Reference< XInterface > LinguProps_CreateInstance(
214 const Reference< XMultiServiceFactory > & /*rSMgr*/ )
216 Reference< XInterface > xService = static_cast<cppu::OWeakObject*>(new LinguProps);
217 return xService;
220 Reference< XPropertySetInfo > SAL_CALL LinguProps::getPropertySetInfo()
222 MutexGuard aGuard( GetLinguMutex() );
224 static Reference< XPropertySetInfo > aRef =
225 new SfxItemPropertySetInfo( aPropertyMap );
226 return aRef;
229 void SAL_CALL LinguProps::setPropertyValue(
230 const OUString& rPropertyName, const Any& rValue )
232 MutexGuard aGuard( GetLinguMutex() );
234 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
235 if (pCur)
237 Any aOld( aConfig.GetProperty( pCur->nWID ) );
238 if (aOld != rValue && aConfig.SetProperty( pCur->nWID, rValue ))
240 PropertyChangeEvent aChgEvt( static_cast<XPropertySet *>(this), rPropertyName,
241 false, pCur->nWID, aOld, rValue );
242 launchEvent( aChgEvt );
247 Any SAL_CALL LinguProps::getPropertyValue( const OUString& rPropertyName )
249 MutexGuard aGuard( GetLinguMutex() );
251 Any aRet;
253 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
254 if(pCur)
256 aRet = aConfig.GetProperty( pCur->nWID );
259 return aRet;
262 void SAL_CALL LinguProps::addPropertyChangeListener(
263 const OUString& rPropertyName,
264 const Reference< XPropertyChangeListener >& rxListener )
266 MutexGuard aGuard( GetLinguMutex() );
268 if (!bDisposing && rxListener.is())
270 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
271 if(pCur)
272 aPropListeners.addInterface( pCur->nWID, rxListener );
276 void SAL_CALL LinguProps::removePropertyChangeListener(
277 const OUString& rPropertyName,
278 const Reference< XPropertyChangeListener >& rxListener )
280 MutexGuard aGuard( GetLinguMutex() );
282 if (!bDisposing && rxListener.is())
284 const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
285 if(pCur)
286 aPropListeners.removeInterface( pCur->nWID, rxListener );
290 void SAL_CALL LinguProps::addVetoableChangeListener(
291 const OUString& /*rPropertyName*/,
292 const Reference< XVetoableChangeListener >& /*xListener*/ )
296 void SAL_CALL LinguProps::removeVetoableChangeListener(
297 const OUString& /*rPropertyName*/,
298 const Reference< XVetoableChangeListener >& /*xListener*/ )
303 void SAL_CALL LinguProps::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
305 MutexGuard aGuard( GetLinguMutex() );
307 Any aOld( aConfig.GetProperty( nHandle ) );
308 if (aOld != rValue && aConfig.SetProperty( nHandle, rValue ))
310 PropertyChangeEvent aChgEvt( static_cast<XPropertySet *>(this),
311 LinguOptions::GetName( nHandle ), false, nHandle, aOld, rValue );
312 launchEvent( aChgEvt );
317 Any SAL_CALL LinguProps::getFastPropertyValue( sal_Int32 nHandle )
319 MutexGuard aGuard( GetLinguMutex() );
321 Any aRes( aConfig.GetProperty( nHandle ) );
322 return aRes;
326 Sequence< PropertyValue > SAL_CALL
327 LinguProps::getPropertyValues()
329 MutexGuard aGuard( GetLinguMutex() );
331 sal_Int32 nLen = aPropertyMap.getSize();
332 Sequence< PropertyValue > aProps( nLen );
333 PropertyValue *pProp = aProps.getArray();
334 PropertyEntryVector_t aPropEntries = aPropertyMap.getPropertyEntries();
335 PropertyEntryVector_t::const_iterator aIt = aPropEntries.begin();
336 for (sal_Int32 i = 0; i < nLen; ++i, ++aIt)
338 PropertyValue &rVal = pProp[i];
339 Any aAny( aConfig.GetProperty( aIt->nWID ) );
341 rVal.Name = aIt->sName;
342 rVal.Handle = aIt->nWID;
343 rVal.Value = aAny;
344 rVal.State = PropertyState_DIRECT_VALUE ;
346 return aProps;
349 void SAL_CALL
350 LinguProps::setPropertyValues( const Sequence< PropertyValue >& rProps )
352 MutexGuard aGuard( GetLinguMutex() );
354 sal_Int32 nLen = rProps.getLength();
355 const PropertyValue *pVal = rProps.getConstArray();
356 for (sal_Int32 i = 0; i < nLen; ++i)
358 const PropertyValue &rVal = pVal[i];
359 setPropertyValue( rVal.Name, rVal.Value );
363 void SAL_CALL
364 LinguProps::dispose()
366 MutexGuard aGuard( GetLinguMutex() );
368 if (!bDisposing)
370 bDisposing = true;
372 //! it's too late to save the options here!
373 // (see AppExitListener for saving)
374 //aOpt.Save(); // save (possible) changes before exiting
376 EventObject aEvtObj( static_cast<XPropertySet *>(this) );
377 aEvtListeners.disposeAndClear( aEvtObj );
378 aPropListeners.disposeAndClear( aEvtObj );
382 void SAL_CALL
383 LinguProps::addEventListener( const Reference< XEventListener >& rxListener )
385 MutexGuard aGuard( GetLinguMutex() );
387 if (!bDisposing && rxListener.is())
388 aEvtListeners.addInterface( rxListener );
391 void SAL_CALL
392 LinguProps::removeEventListener( const Reference< XEventListener >& rxListener )
394 MutexGuard aGuard( GetLinguMutex() );
396 if (!bDisposing && rxListener.is())
397 aEvtListeners.removeInterface( rxListener );
401 // Service specific part
403 // XServiceInfo
404 OUString SAL_CALL LinguProps::getImplementationName()
406 return getImplementationName_Static();
409 // XServiceInfo
410 sal_Bool SAL_CALL LinguProps::supportsService( const OUString& ServiceName )
412 return cppu::supportsService(this, ServiceName);
415 // XServiceInfo
416 uno::Sequence< OUString > SAL_CALL LinguProps::getSupportedServiceNames()
418 return getSupportedServiceNames_Static();
421 // ORegistryServiceManager_Static
422 uno::Sequence< OUString > LinguProps::getSupportedServiceNames_Static()
423 throw()
425 uno::Sequence< OUString > aSNS { "com.sun.star.linguistic2.LinguProperties" };
426 return aSNS;
429 bool LinguProps::getPropertyBool(const OUString& aPropertyName)
431 uno::Any any = getPropertyValue(aPropertyName);
432 bool b = false;
433 any >>= b;
434 return b;
437 sal_Int16 LinguProps::getPropertyInt16(const OUString& aPropertyName)
439 uno::Any any = getPropertyValue(aPropertyName);
440 sal_Int16 b = 0;
441 any >>= b;
442 return b;
445 Locale LinguProps::getPropertyLocale(const OUString& aPropertyName)
447 uno::Any any = getPropertyValue(aPropertyName);
448 css::lang::Locale b;
449 any >>= b;
450 return b;
453 void * LinguProps_getFactory( const sal_Char * pImplName,
454 XMultiServiceFactory *pServiceManager )
456 void * pRet = nullptr;
457 if ( LinguProps::getImplementationName_Static().equalsAscii( pImplName ) )
459 Reference< XSingleServiceFactory > xFactory =
460 cppu::createOneInstanceFactory(
461 pServiceManager,
462 LinguProps::getImplementationName_Static(),
463 LinguProps_CreateInstance,
464 LinguProps::getSupportedServiceNames_Static());
465 // acquire, because we return an interface pointer instead of a reference
466 xFactory->acquire();
467 pRet = xFactory.get();
469 return pRet;
473 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */