xref: /AOO41X/main/linguistic/source/lngopt.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_linguistic.hxx"
30 
31 #include "lngopt.hxx"
32 #include "linguistic/lngprops.hxx"
33 #include "linguistic/misc.hxx"
34 #include <tools/debug.hxx>
35 #include <unotools/lingucfg.hxx>
36 
37 #include <uno/lbnames.h>			// CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
38 #include <cppuhelper/implbase1.hxx>	// helper for implementations
39 
40 #include <cppuhelper/factory.hxx>	// helper for factories
41 #include <com/sun/star/container/XNameAccess.hpp>
42 #include <com/sun/star/registry/XSimpleRegistry.hpp>
43 #include <com/sun/star/registry/XRegistryKey.hpp>
44 #include <com/sun/star/lang/Locale.hpp>
45 #include <com/sun/star/i18n/ScriptType.hpp>
46 #include <unotools/processfactory.hxx>
47 #include <i18npool/mslangid.hxx>
48 
49 using namespace utl;
50 using namespace osl;
51 using namespace rtl;
52 using namespace com::sun::star;
53 using namespace com::sun::star::container;
54 using namespace com::sun::star::beans;
55 using namespace com::sun::star::lang;
56 using namespace com::sun::star::uno;
57 using namespace com::sun::star::linguistic2;
58 using namespace linguistic;
59 
60 using namespace com::sun::star::registry;
61 
62 ///////////////////////////////////////////////////////////////////////////
63 
64 
65 // static member intialization
66 SvtLinguOptions *	LinguOptions::pData	= NULL;
67 vos::ORefCount		LinguOptions::aRefCount;
68 
69 
70 LinguOptions::LinguOptions()
71 {
72 	if (!pData)
73 	{
74 		pData = new SvtLinguOptions;
75 		SvtLinguConfig aLinguCfg;
76 		aLinguCfg.GetOptions( *pData );
77 	}
78 
79 	++aRefCount;
80 }
81 
82 
83 LinguOptions::LinguOptions(const LinguOptions & /*rOpt*/)
84 {
85 	DBG_ASSERT( pData, "lng : data missing" );
86 	++aRefCount;
87 }
88 
89 
90 LinguOptions::~LinguOptions()
91 {
92 	MutexGuard	aGuard( GetLinguMutex() );
93 
94 	if (--aRefCount == 0)
95 	{
96 		delete pData;	pData  = NULL;
97 	}
98 }
99 
100 
101 sal_Bool LinguOptions::SetLocale_Impl( sal_Int16 &rLanguage, Any &rOld, const Any &rVal, sal_Int16 nType)
102 {
103 	sal_Bool bRes = sal_False;
104 
105 	Locale	aNew;
106 	rVal >>= aNew;
107         sal_Int16 nNew = MsLangId::resolveSystemLanguageByScriptType(MsLangId::convertLocaleToLanguage(aNew), nType);
108 	if (nNew != rLanguage)
109 	{
110 		Locale	aLocale( CreateLocale( rLanguage ) );
111 		rOld.setValue( &aLocale, ::getCppuType((Locale*)0 ));
112 		rLanguage = nNew;
113 		bRes = sal_True;
114 	}
115 
116 	return bRes;
117 }
118 
119 
120 sal_Bool LinguOptions::SetValue( Any &rOld, const Any &rVal, sal_Int32 nWID )
121 {
122 	MutexGuard	aGuard( GetLinguMutex() );
123 
124 	sal_Bool bRes = sal_False;
125 
126 	sal_Int16 *pnVal = 0;
127 	sal_Bool  *pbVal = 0;
128 
129 	switch( nWID )
130 	{
131         case WID_IS_GERMAN_PRE_REFORM :     /*! deprecated !*/ break;
132 		case WID_IS_USE_DICTIONARY_LIST :	pbVal = &pData->bIsUseDictionaryList;	break;
133 		case WID_IS_IGNORE_CONTROL_CHARACTERS :	pbVal = &pData->bIsIgnoreControlCharacters;	break;
134 		case WID_IS_HYPH_AUTO : 			pbVal = &pData->bIsHyphAuto;	break;
135 		case WID_IS_HYPH_SPECIAL : 			pbVal = &pData->bIsHyphSpecial;	break;
136 		case WID_IS_SPELL_AUTO : 			pbVal = &pData->bIsSpellAuto;	break;
137         case WID_IS_SPELL_HIDE :            /*! deprecated !*/ break;
138         case WID_IS_SPELL_IN_ALL_LANGUAGES :/*! deprecated !*/ break;
139 		case WID_IS_SPELL_SPECIAL : 		pbVal = &pData->bIsSpellSpecial;	break;
140 		case WID_IS_WRAP_REVERSE : 			pbVal = &pData->bIsSpellReverse;	break;
141 		case WID_DEFAULT_LANGUAGE :			pnVal = &pData->nDefaultLanguage;	break;
142 		case WID_IS_SPELL_CAPITALIZATION :	pbVal = &pData->bIsSpellCapitalization;		break;
143 		case WID_IS_SPELL_WITH_DIGITS :		pbVal = &pData->bIsSpellWithDigits;	break;
144 		case WID_IS_SPELL_UPPER_CASE :		pbVal = &pData->bIsSpellUpperCase;		break;
145 		case WID_HYPH_MIN_LEADING :			pnVal = &pData->nHyphMinLeading;		break;
146 		case WID_HYPH_MIN_TRAILING :		pnVal = &pData->nHyphMinTrailing;	break;
147 		case WID_HYPH_MIN_WORD_LENGTH :		pnVal = &pData->nHyphMinWordLength;	break;
148 		case WID_DEFAULT_LOCALE :
149 		{
150 			bRes = SetLocale_Impl( pData->nDefaultLanguage, rOld, rVal, ::com::sun::star::i18n::ScriptType::LATIN );
151 			break;
152 		}
153 		case WID_DEFAULT_LOCALE_CJK :
154 		{
155 			bRes = SetLocale_Impl( pData->nDefaultLanguage_CJK, rOld, rVal, ::com::sun::star::i18n::ScriptType::ASIAN );
156 			break;
157 		}
158 		case WID_DEFAULT_LOCALE_CTL :
159 		{
160 			bRes = SetLocale_Impl( pData->nDefaultLanguage_CTL, rOld, rVal, ::com::sun::star::i18n::ScriptType::COMPLEX );
161 			break;
162 		}
163 		default :
164 		{
165             DBG_ASSERT( 0,"lng : unknown WID");
166 			bRes = sal_False;
167 		}
168 	}
169 
170 	if (pbVal)
171 	{
172         sal_Bool bNew = sal_False;
173 		rVal >>= bNew;
174 		if (bNew != *pbVal)
175 		{
176 			rOld <<= *pbVal;
177 			*pbVal = bNew;
178 			bRes = sal_True;
179 		}
180 	}
181 	if (pnVal)
182 	{
183         sal_Int16 nNew = 0;
184 		rVal >>= nNew;
185 		if (nNew != *pnVal)
186 		{
187 			rOld <<= *pnVal;
188 			*pnVal = nNew;
189 			bRes = sal_True;
190 		}
191 	}
192 
193 //	if (bRes)
194 //		pData->SetModified();
195 
196 	return bRes;
197 }
198 
199 void LinguOptions::GetValue( Any &rVal, sal_Int32 nWID ) const
200 {
201 	MutexGuard	aGuard( GetLinguMutex() );
202 
203 	sal_Int16 *pnVal = 0;
204 	sal_Bool  *pbVal = 0;
205     sal_Bool  bDummy = sal_False;
206 
207 	switch( nWID )
208 	{
209         case WID_IS_GERMAN_PRE_REFORM :     pbVal = &bDummy; /*! deprecated !*/ break;
210 		case WID_IS_USE_DICTIONARY_LIST :	pbVal = &pData->bIsUseDictionaryList;	break;
211 		case WID_IS_IGNORE_CONTROL_CHARACTERS :	pbVal = &pData->bIsIgnoreControlCharacters;	break;
212 		case WID_IS_HYPH_AUTO : 			pbVal = &pData->bIsHyphAuto;	break;
213 		case WID_IS_HYPH_SPECIAL : 			pbVal = &pData->bIsHyphSpecial;	break;
214 		case WID_IS_SPELL_AUTO : 			pbVal = &pData->bIsSpellAuto;	break;
215         case WID_IS_SPELL_HIDE :            pbVal = &bDummy; /*! deprecated !*/ break;
216         case WID_IS_SPELL_IN_ALL_LANGUAGES :pbVal = &bDummy; /*! deprecated !*/ break;
217 		case WID_IS_SPELL_SPECIAL : 		pbVal = &pData->bIsSpellSpecial;	break;
218 		case WID_IS_WRAP_REVERSE : 			pbVal = &pData->bIsSpellReverse;	break;
219 		case WID_DEFAULT_LANGUAGE :			pnVal = &pData->nDefaultLanguage;	break;
220 		case WID_IS_SPELL_CAPITALIZATION :	pbVal = &pData->bIsSpellCapitalization;		break;
221 		case WID_IS_SPELL_WITH_DIGITS :		pbVal = &pData->bIsSpellWithDigits;	break;
222 		case WID_IS_SPELL_UPPER_CASE :		pbVal = &pData->bIsSpellUpperCase;		break;
223 		case WID_HYPH_MIN_LEADING :			pnVal = &pData->nHyphMinLeading;		break;
224 		case WID_HYPH_MIN_TRAILING :		pnVal = &pData->nHyphMinTrailing;	break;
225 		case WID_HYPH_MIN_WORD_LENGTH :		pnVal = &pData->nHyphMinWordLength;	break;
226 		case WID_DEFAULT_LOCALE :
227 		{
228 			Locale aLocale( MsLangId::convertLanguageToLocale( pData->nDefaultLanguage ) );
229 			rVal.setValue( &aLocale, ::getCppuType((Locale*)0 ));
230 			break;
231 		}
232 		case WID_DEFAULT_LOCALE_CJK :
233 		{
234 			Locale aLocale( MsLangId::convertLanguageToLocale( pData->nDefaultLanguage_CJK ) );
235 			rVal.setValue( &aLocale, ::getCppuType((Locale*)0 ));
236 			break;
237 		}
238 		case WID_DEFAULT_LOCALE_CTL :
239 		{
240 			Locale aLocale( MsLangId::convertLanguageToLocale( pData->nDefaultLanguage_CTL ) );
241 			rVal.setValue( &aLocale, ::getCppuType((Locale*)0 ));
242 			break;
243 		}
244 		default :
245 		{
246             DBG_ASSERT( 0,"lng : unknown WID");
247 		}
248 	}
249 
250 	if (pbVal)
251 		rVal <<= *pbVal;
252 	if (pnVal)
253 		rVal <<= *pnVal;
254 }
255 
256 
257 struct WID_Name
258 {
259 	sal_Int32		 nWID;
260 	const char	*pPropertyName;
261 };
262 
263 //! order of entries is import (see LinguOptions::GetName)
264 //! since the WID is used as index in this table!
265 WID_Name aWID_Name[] =
266 {
267     { 0,                                  0 },
268     { WID_IS_USE_DICTIONARY_LIST,         UPN_IS_USE_DICTIONARY_LIST },
269     { WID_IS_IGNORE_CONTROL_CHARACTERS,   UPN_IS_IGNORE_CONTROL_CHARACTERS },
270     { WID_IS_SPELL_UPPER_CASE,            UPN_IS_SPELL_UPPER_CASE },
271     { WID_IS_SPELL_WITH_DIGITS,           UPN_IS_SPELL_WITH_DIGITS },
272     { WID_IS_SPELL_CAPITALIZATION,        UPN_IS_SPELL_CAPITALIZATION },
273     { WID_HYPH_MIN_LEADING,               UPN_HYPH_MIN_LEADING },
274     { WID_HYPH_MIN_TRAILING,              UPN_HYPH_MIN_TRAILING },
275     { WID_HYPH_MIN_WORD_LENGTH,           UPN_HYPH_MIN_WORD_LENGTH },
276     { WID_DEFAULT_LOCALE,                 UPN_DEFAULT_LOCALE },
277     { WID_IS_SPELL_AUTO,                  UPN_IS_SPELL_AUTO },
278     { 0,                                  0 },
279     { 0,                                  0 },
280     { WID_IS_SPELL_SPECIAL,               UPN_IS_SPELL_SPECIAL },
281     { WID_IS_HYPH_AUTO,                   UPN_IS_HYPH_AUTO },
282     { WID_IS_HYPH_SPECIAL,                UPN_IS_HYPH_SPECIAL },
283     { WID_IS_WRAP_REVERSE,                UPN_IS_WRAP_REVERSE },
284     { 0,                                  0 },
285     { 0,                                  0 },
286     { 0,                                  0 },
287     { 0,                                  0 },
288     { WID_DEFAULT_LANGUAGE,               UPN_DEFAULT_LANGUAGE },
289     { WID_DEFAULT_LOCALE_CJK,             UPN_DEFAULT_LOCALE_CJK },
290     { WID_DEFAULT_LOCALE_CTL,             UPN_DEFAULT_LOCALE_CTL }
291 };
292 
293 
294 OUString LinguOptions::GetName( sal_Int32 nWID )
295 {
296 	MutexGuard	aGuard( GetLinguMutex() );
297 
298 	OUString aRes;
299 
300 	sal_Int32 nLen = sizeof( aWID_Name ) / sizeof( aWID_Name[0] );
301 	if (0 <= nWID  &&  nWID < nLen
302 		&& aWID_Name[ nWID ].nWID == nWID)
303 	{
304 		aRes = OUString( RTL_CONSTASCII_USTRINGPARAM(
305 				aWID_Name[ nWID ].pPropertyName ) );
306 	}
307 	else
308 	{
309         DBG_ASSERT( 0,"lng : unknown WID");
310 	}
311 
312 	return aRes;
313 }
314 
315 
316 ///////////////////////////////////////////////////////////////////////////
317 
318 //! map must be sorted by first entry in alphabetical increasing order.
319 const SfxItemPropertyMapEntry* lcl_GetLinguProps()
320 {
321     static const SfxItemPropertyMapEntry aLinguProps[] =
322     {
323         { MAP_CHAR_LEN(UPN_DEFAULT_LANGUAGE),           WID_DEFAULT_LANGUAGE,
324                 &::getCppuType( (sal_Int16*)0 ),    0, 0 },
325         { MAP_CHAR_LEN(UPN_DEFAULT_LOCALE),             WID_DEFAULT_LOCALE,
326                 &::getCppuType( (Locale* )0),       0, 0 },
327         { MAP_CHAR_LEN(UPN_DEFAULT_LOCALE_CJK),         WID_DEFAULT_LOCALE_CJK,
328                 &::getCppuType( (Locale* )0),       0, 0 },
329         { MAP_CHAR_LEN(UPN_DEFAULT_LOCALE_CTL),         WID_DEFAULT_LOCALE_CTL,
330                 &::getCppuType( (Locale* )0),       0, 0 },
331         { MAP_CHAR_LEN(UPN_HYPH_MIN_LEADING),           WID_HYPH_MIN_LEADING,
332                 &::getCppuType( (sal_Int16*)0 ),    0, 0 },
333         { MAP_CHAR_LEN(UPN_HYPH_MIN_TRAILING),          WID_HYPH_MIN_TRAILING,
334                 &::getCppuType( (sal_Int16*)0 ),    0, 0 },
335         { MAP_CHAR_LEN(UPN_HYPH_MIN_WORD_LENGTH),       WID_HYPH_MIN_WORD_LENGTH,
336                 &::getCppuType( (sal_Int16*)0 ),    0, 0 },
337         { MAP_CHAR_LEN(UPN_IS_GERMAN_PRE_REFORM),       WID_IS_GERMAN_PRE_REFORM,       /*! deprecated !*/
338                 &::getBooleanCppuType(),            0, 0 },
339         { MAP_CHAR_LEN(UPN_IS_HYPH_AUTO),               WID_IS_HYPH_AUTO,
340                 &::getBooleanCppuType(),            0, 0 },
341         { MAP_CHAR_LEN(UPN_IS_HYPH_SPECIAL),            WID_IS_HYPH_SPECIAL,
342                 &::getBooleanCppuType(),            0, 0 },
343         { MAP_CHAR_LEN(UPN_IS_IGNORE_CONTROL_CHARACTERS),   WID_IS_IGNORE_CONTROL_CHARACTERS,
344                 &::getBooleanCppuType(),            0, 0 },
345         { MAP_CHAR_LEN(UPN_IS_SPELL_AUTO),              WID_IS_SPELL_AUTO,
346                 &::getBooleanCppuType(),            0, 0 },
347         { MAP_CHAR_LEN(UPN_IS_SPELL_CAPITALIZATION),    WID_IS_SPELL_CAPITALIZATION,
348                 &::getBooleanCppuType(),            0, 0 },
349         { MAP_CHAR_LEN(UPN_IS_SPELL_HIDE),              WID_IS_SPELL_HIDE,              /*! deprecated !*/
350                 &::getBooleanCppuType(),            0, 0 },
351         { MAP_CHAR_LEN(UPN_IS_SPELL_IN_ALL_LANGUAGES),  WID_IS_SPELL_IN_ALL_LANGUAGES,  /*! deprecated !*/
352                 &::getBooleanCppuType(),            0, 0 },
353         { MAP_CHAR_LEN(UPN_IS_SPELL_SPECIAL),           WID_IS_SPELL_SPECIAL,
354                 &::getBooleanCppuType(),            0, 0 },
355         { MAP_CHAR_LEN(UPN_IS_SPELL_UPPER_CASE),        WID_IS_SPELL_UPPER_CASE,
356                 &::getBooleanCppuType(),            0, 0 },
357         { MAP_CHAR_LEN(UPN_IS_SPELL_WITH_DIGITS),       WID_IS_SPELL_WITH_DIGITS,
358                 &::getBooleanCppuType(),            0, 0 },
359         { MAP_CHAR_LEN(UPN_IS_USE_DICTIONARY_LIST),     WID_IS_USE_DICTIONARY_LIST,
360                 &::getBooleanCppuType(),            0, 0 },
361         { MAP_CHAR_LEN(UPN_IS_WRAP_REVERSE),            WID_IS_WRAP_REVERSE,
362                 &::getBooleanCppuType(),            0, 0 },
363         { 0,0,0,0,0,0 }
364     };
365     return aLinguProps;
366 }
367 LinguProps::LinguProps() :
368 	aEvtListeners	(GetLinguMutex()),
369 	aPropListeners	(GetLinguMutex()),
370     aPropertyMap(lcl_GetLinguProps())
371 {
372 	bDisposing = sal_False;
373 }
374 
375 void LinguProps::launchEvent( const PropertyChangeEvent &rEvt ) const
376 {
377 	cppu::OInterfaceContainerHelper *pContainer =
378 			aPropListeners.getContainer( rEvt.PropertyHandle );
379 	if (pContainer)
380 	{
381 		cppu::OInterfaceIteratorHelper aIt( *pContainer );
382 		while (aIt.hasMoreElements())
383 		{
384             Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY );
385 			if (xRef.is())
386 				xRef->propertyChange( rEvt );
387 		}
388 	}
389 }
390 
391 Reference< XInterface > SAL_CALL LinguProps_CreateInstance(
392             const Reference< XMultiServiceFactory > & /*rSMgr*/ )
393 		throw(Exception)
394 {
395 	Reference< XInterface > xService = (cppu::OWeakObject*)new LinguProps;
396 	return xService;
397 }
398 
399 Reference< XPropertySetInfo > SAL_CALL LinguProps::getPropertySetInfo()
400 		throw(RuntimeException)
401 {
402 	MutexGuard	aGuard( GetLinguMutex() );
403 
404 	static Reference< XPropertySetInfo > aRef =
405             new SfxItemPropertySetInfo( &aPropertyMap );
406 	return aRef;
407 }
408 
409 void SAL_CALL LinguProps::setPropertyValue(
410             const OUString& rPropertyName, const Any& rValue )
411 		throw(UnknownPropertyException, PropertyVetoException,
412 			  IllegalArgumentException, WrappedTargetException, RuntimeException)
413 {
414 	MutexGuard	aGuard( GetLinguMutex() );
415 
416     const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
417 	if (pCur)
418 	{
419         Any aOld( aConfig.GetProperty( pCur->nWID ) );
420         if (aOld != rValue && aConfig.SetProperty( pCur->nWID, rValue ))
421 		{
422 			PropertyChangeEvent aChgEvt( (XPropertySet *) this, rPropertyName,
423                     sal_False, pCur->nWID, aOld, rValue );
424 			launchEvent( aChgEvt );
425 		}
426 	}
427 #ifdef LINGU_EXCEPTIONS
428 	else
429 	{
430 		throw UnknownPropertyException();
431 	}
432 #endif
433 }
434 
435 Any SAL_CALL LinguProps::getPropertyValue( const OUString& rPropertyName )
436 		throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
437 {
438 	MutexGuard	aGuard( GetLinguMutex() );
439 
440 	Any aRet;
441 
442     const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
443 	if(pCur)
444 	{
445         aRet = aConfig.GetProperty( pCur->nWID );
446 	}
447 #ifdef LINGU_EXCEPTIONS
448 	else
449 	{
450 		throw UnknownPropertyException();
451 	}
452 #endif
453 
454 	return aRet;
455 }
456 
457 void SAL_CALL LinguProps::addPropertyChangeListener(
458 			const OUString& rPropertyName,
459 			const Reference< XPropertyChangeListener >& rxListener )
460 		throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
461 {
462 	MutexGuard	aGuard( GetLinguMutex() );
463 
464 	if (!bDisposing && rxListener.is())
465 	{
466         const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
467 		if(pCur)
468 			aPropListeners.addInterface( pCur->nWID, rxListener );
469 #ifdef LINGU_EXCEPTIONS
470 		else
471 		{
472 			throw UnknownPropertyException();
473 		}
474 #endif
475 	}
476 }
477 
478 void SAL_CALL LinguProps::removePropertyChangeListener(
479 			const OUString& rPropertyName,
480 			const Reference< XPropertyChangeListener >& rxListener )
481 		throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
482 {
483 	MutexGuard	aGuard( GetLinguMutex() );
484 
485 	if (!bDisposing && rxListener.is())
486 	{
487         const SfxItemPropertySimpleEntry* pCur = aPropertyMap.getByName( rPropertyName );
488 		if(pCur)
489 			aPropListeners.removeInterface( pCur->nWID, rxListener );
490 #ifdef LINGU_EXCEPTIONS
491 		else
492 		{
493 			throw UnknownPropertyException();
494 		}
495 #endif
496 	}
497 }
498 
499 void SAL_CALL LinguProps::addVetoableChangeListener(
500             const OUString& /*rPropertyName*/,
501             const Reference< XVetoableChangeListener >& /*xListener*/ )
502 		throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
503 {
504 //	MutexGuard	aGuard( GetLinguMutex() );
505 }
506 
507 void SAL_CALL LinguProps::removeVetoableChangeListener(
508             const OUString& /*rPropertyName*/,
509             const Reference< XVetoableChangeListener >& /*xListener*/ )
510 		throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
511 {
512 //	MutexGuard	aGuard( GetLinguMutex() );
513 }
514 
515 
516 void SAL_CALL LinguProps::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
517 		throw(UnknownPropertyException, PropertyVetoException,
518 			  IllegalArgumentException, WrappedTargetException, RuntimeException)
519 {
520 	MutexGuard	aGuard( GetLinguMutex() );
521 
522     Any aOld( aConfig.GetProperty( nHandle ) );
523     if (aOld != rValue && aConfig.SetProperty( nHandle, rValue ))
524 	{
525 		PropertyChangeEvent aChgEvt( (XPropertySet *) this,
526                 LinguOptions::GetName( nHandle ), sal_False, nHandle, aOld, rValue );
527 		launchEvent( aChgEvt );
528 	}
529 }
530 
531 
532 Any SAL_CALL LinguProps::getFastPropertyValue( sal_Int32 nHandle )
533 		throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
534 {
535 	MutexGuard	aGuard( GetLinguMutex() );
536 
537     Any aRes( aConfig.GetProperty( nHandle ) );
538 	return aRes;
539 }
540 
541 
542 Sequence< PropertyValue > SAL_CALL
543 	LinguProps::getPropertyValues()
544 		throw(RuntimeException)
545 {
546 	MutexGuard	aGuard( GetLinguMutex() );
547 
548     sal_Int32 nLen = aPropertyMap.getSize();
549 	Sequence< PropertyValue > aProps( nLen );
550     PropertyValue *pProp = aProps.getArray();
551     PropertyEntryVector_t aPropEntries = aPropertyMap.getPropertyEntries();
552     PropertyEntryVector_t::const_iterator aIt = aPropEntries.begin();
553     for (sal_Int32 i = 0;  i < nLen;  ++i, ++aIt)
554 	{
555 		PropertyValue &rVal = pProp[i];
556         Any aAny( aConfig.GetProperty( aIt->nWID ) );
557 
558         rVal.Name   = aIt->sName;
559         rVal.Handle = aIt->nWID;
560     	rVal.Value	= aAny;
561     	rVal.State	= PropertyState_DIRECT_VALUE ;
562 	}
563 	return aProps;
564 }
565 
566 void SAL_CALL
567 	LinguProps::setPropertyValues( const Sequence< PropertyValue >& rProps )
568 		throw(UnknownPropertyException, PropertyVetoException,
569 			  IllegalArgumentException, WrappedTargetException, RuntimeException)
570 {
571 	MutexGuard	aGuard( GetLinguMutex() );
572 
573 	sal_Int32 nLen = rProps.getLength();
574 	const PropertyValue *pVal = rProps.getConstArray();
575 	for (sal_Int32 i = 0;  i < nLen;  ++i)
576 	{
577         const PropertyValue &rVal = pVal[i];
578         setPropertyValue( rVal.Name, rVal.Value );
579 	}
580 }
581 
582 void SAL_CALL
583 	LinguProps::dispose()
584 		throw(RuntimeException)
585 {
586 	MutexGuard	aGuard( GetLinguMutex() );
587 
588 	if (!bDisposing)
589 	{
590 		bDisposing = sal_True;
591 
592 		//! its too late to save the options here!
593 		// (see AppExitListener for saving)
594 		//aOpt.Save();	// save (possible) changes before exiting
595 
596 		EventObject	aEvtObj( (XPropertySet *) this );
597 		aEvtListeners.disposeAndClear( aEvtObj );
598 		aPropListeners.disposeAndClear( aEvtObj );
599 	}
600 }
601 
602 void SAL_CALL
603 	LinguProps::addEventListener( const Reference< XEventListener >& rxListener )
604 		throw(RuntimeException)
605 {
606 	MutexGuard	aGuard( GetLinguMutex() );
607 
608 	if (!bDisposing && rxListener.is())
609 		aEvtListeners.addInterface( rxListener );
610 }
611 
612 void SAL_CALL
613 	LinguProps::removeEventListener( const Reference< XEventListener >& rxListener )
614 		throw(RuntimeException)
615 {
616 	MutexGuard	aGuard( GetLinguMutex() );
617 
618 	if (!bDisposing && rxListener.is())
619 		aEvtListeners.removeInterface( rxListener );
620 }
621 
622 
623 ///////////////////////////////////////////////////////////////////////////
624 // Service specific part
625 //
626 
627 // XServiceInfo
628 OUString SAL_CALL LinguProps::getImplementationName()
629 		throw(RuntimeException)
630 {
631 	MutexGuard	aGuard( GetLinguMutex() );
632 	return getImplementationName_Static();
633 }
634 
635 // XServiceInfo
636 sal_Bool SAL_CALL LinguProps::supportsService( const OUString& ServiceName )
637 		throw(RuntimeException)
638 {
639 	MutexGuard	aGuard( GetLinguMutex() );
640 
641 	uno::Sequence< OUString > aSNL = getSupportedServiceNames();
642 	const OUString * pArray = aSNL.getConstArray();
643 	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
644 		if( pArray[i] == ServiceName )
645 			return sal_True;
646 	return sal_False;
647 }
648 
649 // XServiceInfo
650 uno::Sequence< OUString > SAL_CALL LinguProps::getSupportedServiceNames()
651 		throw(RuntimeException)
652 {
653 	MutexGuard	aGuard( GetLinguMutex() );
654 	return getSupportedServiceNames_Static();
655 }
656 
657 // ORegistryServiceManager_Static
658 uno::Sequence< OUString > LinguProps::getSupportedServiceNames_Static()
659 		throw()
660 {
661 	MutexGuard	aGuard( GetLinguMutex() );
662 
663 	uno::Sequence< OUString > aSNS( 1 );	// auch mehr als 1 Service moeglich
664 	aSNS.getArray()[0] = A2OU( SN_LINGU_PROPERTIES );
665 	return aSNS;
666 }
667 
668 void * SAL_CALL LinguProps_getFactory( const sal_Char * pImplName,
669 			XMultiServiceFactory *pServiceManager, void * )
670 {
671 	void * pRet = 0;
672 	if ( !LinguProps::getImplementationName_Static().compareToAscii( pImplName ) )
673 	{
674 		Reference< XSingleServiceFactory > xFactory =
675 			cppu::createOneInstanceFactory(
676 				pServiceManager,
677 				LinguProps::getImplementationName_Static(),
678 				LinguProps_CreateInstance,
679 				LinguProps::getSupportedServiceNames_Static());
680 		// acquire, because we return an interface pointer instead of a reference
681 		xFactory->acquire();
682 		pRet = xFactory.get();
683 	}
684 	return pRet;
685 }
686 
687 ///////////////////////////////////////////////////////////////////////////
688 
689