1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_unotools.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/container/XNameReplace.hpp>
38*cdf0e10cSrcweir #include "com/sun/star/util/XMacroExpander.hpp"
39*cdf0e10cSrcweir #include "com/sun/star/beans/XPropertySet.hpp"
40*cdf0e10cSrcweir #include <rtl/uri.hxx>
41*cdf0e10cSrcweir #include <vos/mutex.hxx>
42*cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
43*cdf0e10cSrcweir #include <tools/debug.hxx>
44*cdf0e10cSrcweir #include <tools/string.hxx>
45*cdf0e10cSrcweir #include <unotools/lingucfg.hxx>
46*cdf0e10cSrcweir #include <unotools/linguprops.hxx>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #include <itemholder1.hxx>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir using namespace rtl;
53*cdf0e10cSrcweir using namespace com::sun::star;
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #define A2OU(x)        ::rtl::OUString::createFromAscii( x )
56*cdf0e10cSrcweir #define EXPAND_PROTOCOL     "vnd.sun.star.expand:"
57*cdf0e10cSrcweir #define FILE_PROTOCOL       "file:///"
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir static osl::Mutex &  GetOwnMutex()
63*cdf0e10cSrcweir {
64*cdf0e10cSrcweir     static osl::Mutex aMutex;
65*cdf0e10cSrcweir     return aMutex;
66*cdf0e10cSrcweir }
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir static sal_Bool lcl_SetLocale( sal_Int16 &rLanguage, const uno::Any &rVal )
73*cdf0e10cSrcweir {
74*cdf0e10cSrcweir     sal_Bool bSucc = sal_False;
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir     lang::Locale aNew;
77*cdf0e10cSrcweir     if (rVal >>= aNew)	// conversion successful?
78*cdf0e10cSrcweir     {
79*cdf0e10cSrcweir         sal_Int16 nNew = MsLangId::convertLocaleToLanguage( aNew );
80*cdf0e10cSrcweir         if (nNew != rLanguage)
81*cdf0e10cSrcweir         {
82*cdf0e10cSrcweir             rLanguage = nNew;
83*cdf0e10cSrcweir             bSucc = sal_True;
84*cdf0e10cSrcweir         }
85*cdf0e10cSrcweir     }
86*cdf0e10cSrcweir     return bSucc;
87*cdf0e10cSrcweir }
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir static inline const OUString lcl_LanguageToCfgLocaleStr( sal_Int16 nLanguage )
91*cdf0e10cSrcweir {
92*cdf0e10cSrcweir     OUString aRes;
93*cdf0e10cSrcweir     if (LANGUAGE_SYSTEM != nLanguage)
94*cdf0e10cSrcweir         aRes = MsLangId::convertLanguageToIsoString( nLanguage );
95*cdf0e10cSrcweir     return aRes;
96*cdf0e10cSrcweir }
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir static sal_Int16 lcl_CfgAnyToLanguage( const uno::Any &rVal )
100*cdf0e10cSrcweir {
101*cdf0e10cSrcweir     OUString aTmp;
102*cdf0e10cSrcweir     rVal >>= aTmp;
103*cdf0e10cSrcweir     return (aTmp.getLength() == 0) ? LANGUAGE_SYSTEM : MsLangId::convertIsoStringToLanguage( aTmp );
104*cdf0e10cSrcweir }
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir SvtLinguOptions::SvtLinguOptions()
110*cdf0e10cSrcweir {
111*cdf0e10cSrcweir     nDefaultLanguage = LANGUAGE_NONE;
112*cdf0e10cSrcweir 	nDefaultLanguage_CJK = LANGUAGE_NONE;
113*cdf0e10cSrcweir 	nDefaultLanguage_CTL = LANGUAGE_NONE;
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir 	// general options
116*cdf0e10cSrcweir 	bIsUseDictionaryList	=
117*cdf0e10cSrcweir 	bIsIgnoreControlCharacters	= sal_True;
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir 	// spelling options
120*cdf0e10cSrcweir 	bIsSpellCapitalization	=
121*cdf0e10cSrcweir 	bIsSpellSpecial			= sal_True;
122*cdf0e10cSrcweir 	bIsSpellAuto			=
123*cdf0e10cSrcweir 	bIsSpellReverse			=
124*cdf0e10cSrcweir 	bIsSpellWithDigits		=
125*cdf0e10cSrcweir 	bIsSpellUpperCase		= sal_False;
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir     // text conversion options
128*cdf0e10cSrcweir     bIsIgnorePostPositionalWord     = sal_True;
129*cdf0e10cSrcweir     bIsAutoCloseDialog              =
130*cdf0e10cSrcweir     bIsShowEntriesRecentlyUsedFirst =
131*cdf0e10cSrcweir     bIsAutoReplaceUniqueEntries     = sal_False;
132*cdf0e10cSrcweir     bIsDirectionToSimplified        = sal_True;
133*cdf0e10cSrcweir     bIsUseCharacterVariants         =
134*cdf0e10cSrcweir     bIsTranslateCommonTerms         =
135*cdf0e10cSrcweir     bIsReverseMapping               = sal_False;
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir     bROIsDirectionToSimplified      =
138*cdf0e10cSrcweir     bROIsUseCharacterVariants       =
139*cdf0e10cSrcweir     bROIsTranslateCommonTerms       =
140*cdf0e10cSrcweir     bROIsReverseMapping             = sal_False;
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 	// hyphenation options
143*cdf0e10cSrcweir 	bIsHyphSpecial			= sal_True;
144*cdf0e10cSrcweir 	bIsHyphAuto				= sal_False;
145*cdf0e10cSrcweir 	nHyphMinLeading			=
146*cdf0e10cSrcweir 	nHyphMinTrailing		= 2;
147*cdf0e10cSrcweir 	nHyphMinWordLength		= 0;
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir     nDataFilesChangedCheckValue = 0;
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir     //grammar options
152*cdf0e10cSrcweir     bIsGrammarAuto = sal_False,
153*cdf0e10cSrcweir     bIsGrammarInteractive = sal_False;
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir class SvtLinguConfigItem : public utl::ConfigItem
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir     SvtLinguOptions     aOpt;
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir     // disallow copy-constructor and assignment-operator for now
166*cdf0e10cSrcweir     SvtLinguConfigItem( const SvtLinguConfigItem & );
167*cdf0e10cSrcweir     SvtLinguConfigItem & operator = ( const SvtLinguConfigItem & );
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir     static sal_Bool GetHdlByName( sal_Int32 &rnHdl, const OUString &rPropertyName, sal_Bool bFullPropName = sal_False );
170*cdf0e10cSrcweir     static const uno::Sequence< OUString > & GetPropertyNames();
171*cdf0e10cSrcweir     sal_Bool                LoadOptions( const uno::Sequence< OUString > &rProperyNames );
172*cdf0e10cSrcweir     sal_Bool                SaveOptions( const uno::Sequence< OUString > &rProperyNames );
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir public:
175*cdf0e10cSrcweir     SvtLinguConfigItem();
176*cdf0e10cSrcweir     virtual ~SvtLinguConfigItem();
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir     // utl::ConfigItem
179*cdf0e10cSrcweir     virtual void    Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames );
180*cdf0e10cSrcweir     virtual void    Commit();
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir     // make some protected functions of utl::ConfigItem public
183*cdf0e10cSrcweir     using utl::ConfigItem::GetNodeNames;
184*cdf0e10cSrcweir     using utl::ConfigItem::GetProperties;
185*cdf0e10cSrcweir     //using utl::ConfigItem::PutProperties;
186*cdf0e10cSrcweir     //using utl::ConfigItem::SetSetProperties;
187*cdf0e10cSrcweir     using utl::ConfigItem::ReplaceSetProperties;
188*cdf0e10cSrcweir     //using utl::ConfigItem::GetReadOnlyStates;
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir     com::sun::star::uno::Any
192*cdf0e10cSrcweir             GetProperty( const rtl::OUString &rPropertyName ) const;
193*cdf0e10cSrcweir     com::sun::star::uno::Any
194*cdf0e10cSrcweir             GetProperty( sal_Int32 nPropertyHandle ) const;
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir     sal_Bool    SetProperty( const rtl::OUString &rPropertyName,
197*cdf0e10cSrcweir                          const com::sun::star::uno::Any &rValue );
198*cdf0e10cSrcweir     sal_Bool    SetProperty( sal_Int32 nPropertyHandle,
199*cdf0e10cSrcweir                          const com::sun::star::uno::Any &rValue );
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir     sal_Bool    GetOptions( SvtLinguOptions &rOptions ) const;
202*cdf0e10cSrcweir     sal_Bool    SetOptions( const SvtLinguOptions &rOptions );
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir     sal_Bool    IsReadOnly( const rtl::OUString &rPropertyName ) const;
205*cdf0e10cSrcweir     sal_Bool    IsReadOnly( sal_Int32 nPropertyHandle ) const;
206*cdf0e10cSrcweir };
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir SvtLinguConfigItem::SvtLinguConfigItem() :
210*cdf0e10cSrcweir     utl::ConfigItem( String::CreateFromAscii( "Office.Linguistic" ) )
211*cdf0e10cSrcweir {
212*cdf0e10cSrcweir     LoadOptions( GetPropertyNames() );
213*cdf0e10cSrcweir     ClearModified();
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir     // request notify events when properties change
216*cdf0e10cSrcweir     EnableNotification( GetPropertyNames() );
217*cdf0e10cSrcweir }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir SvtLinguConfigItem::~SvtLinguConfigItem()
221*cdf0e10cSrcweir {
222*cdf0e10cSrcweir     //! Commit (SaveOptions) will be called by the d-tor of the base called !
223*cdf0e10cSrcweir }
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames )
227*cdf0e10cSrcweir {
228*cdf0e10cSrcweir     LoadOptions( rPropertyNames );
229*cdf0e10cSrcweir 	NotifyListeners(0);
230*cdf0e10cSrcweir }
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir void SvtLinguConfigItem::Commit()
234*cdf0e10cSrcweir {
235*cdf0e10cSrcweir     SaveOptions( GetPropertyNames() );
236*cdf0e10cSrcweir }
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir static struct NamesToHdl
240*cdf0e10cSrcweir {
241*cdf0e10cSrcweir     const char   *pFullPropName;      // full qualified name as used in configuration
242*cdf0e10cSrcweir     const char   *pPropName;          // property name only (atom) of above
243*cdf0e10cSrcweir     sal_Int32   nHdl;               // numeric handle representing the property
244*cdf0e10cSrcweir }aNamesToHdl[] =
245*cdf0e10cSrcweir {
246*cdf0e10cSrcweir {/*  0 */    "General/DefaultLocale",                         UPN_DEFAULT_LOCALE,                    UPH_DEFAULT_LOCALE},
247*cdf0e10cSrcweir {/*  1 */    "General/DictionaryList/ActiveDictionaries",     UPN_ACTIVE_DICTIONARIES,               UPH_ACTIVE_DICTIONARIES},
248*cdf0e10cSrcweir {/*  2 */    "General/DictionaryList/IsUseDictionaryList",    UPN_IS_USE_DICTIONARY_LIST,            UPH_IS_USE_DICTIONARY_LIST},
249*cdf0e10cSrcweir {/*  3 */    "General/IsIgnoreControlCharacters",             UPN_IS_IGNORE_CONTROL_CHARACTERS,      UPH_IS_IGNORE_CONTROL_CHARACTERS},
250*cdf0e10cSrcweir {/*  5 */    "General/DefaultLocale_CJK",                     UPN_DEFAULT_LOCALE_CJK,                UPH_DEFAULT_LOCALE_CJK},
251*cdf0e10cSrcweir {/*  6 */    "General/DefaultLocale_CTL",                     UPN_DEFAULT_LOCALE_CTL,                UPH_DEFAULT_LOCALE_CTL},
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir {/*  7 */    "SpellChecking/IsSpellUpperCase",                UPN_IS_SPELL_UPPER_CASE,               UPH_IS_SPELL_UPPER_CASE},
254*cdf0e10cSrcweir {/*  8 */    "SpellChecking/IsSpellWithDigits",               UPN_IS_SPELL_WITH_DIGITS,              UPH_IS_SPELL_WITH_DIGITS},
255*cdf0e10cSrcweir {/*  9 */    "SpellChecking/IsSpellCapitalization",           UPN_IS_SPELL_CAPITALIZATION,           UPH_IS_SPELL_CAPITALIZATION},
256*cdf0e10cSrcweir {/* 10 */    "SpellChecking/IsSpellAuto",                     UPN_IS_SPELL_AUTO,                     UPH_IS_SPELL_AUTO},
257*cdf0e10cSrcweir {/* 11 */    "SpellChecking/IsSpellSpecial",                  UPN_IS_SPELL_SPECIAL,                  UPH_IS_SPELL_SPECIAL},
258*cdf0e10cSrcweir {/* 14 */    "SpellChecking/IsReverseDirection",              UPN_IS_WRAP_REVERSE,                   UPH_IS_WRAP_REVERSE},
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir {/* 15 */    "Hyphenation/MinLeading",                        UPN_HYPH_MIN_LEADING,                  UPH_HYPH_MIN_LEADING},
261*cdf0e10cSrcweir {/* 16 */    "Hyphenation/MinTrailing",                       UPN_HYPH_MIN_TRAILING,                 UPH_HYPH_MIN_TRAILING},
262*cdf0e10cSrcweir {/* 17 */    "Hyphenation/MinWordLength",                     UPN_HYPH_MIN_WORD_LENGTH,              UPH_HYPH_MIN_WORD_LENGTH},
263*cdf0e10cSrcweir {/* 18 */    "Hyphenation/IsHyphSpecial",                     UPN_IS_HYPH_SPECIAL,                   UPH_IS_HYPH_SPECIAL},
264*cdf0e10cSrcweir {/* 19 */    "Hyphenation/IsHyphAuto",                        UPN_IS_HYPH_AUTO,                      UPH_IS_HYPH_AUTO},
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir {/* 20 */    "TextConversion/ActiveConversionDictionaries",   UPN_ACTIVE_CONVERSION_DICTIONARIES,        UPH_ACTIVE_CONVERSION_DICTIONARIES},
267*cdf0e10cSrcweir {/* 21 */    "TextConversion/IsIgnorePostPositionalWord",     UPN_IS_IGNORE_POST_POSITIONAL_WORD,        UPH_IS_IGNORE_POST_POSITIONAL_WORD},
268*cdf0e10cSrcweir {/* 22 */    "TextConversion/IsAutoCloseDialog",              UPN_IS_AUTO_CLOSE_DIALOG,                  UPH_IS_AUTO_CLOSE_DIALOG},
269*cdf0e10cSrcweir {/* 23 */    "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST,   UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
270*cdf0e10cSrcweir {/* 24 */    "TextConversion/IsAutoReplaceUniqueEntries",     UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES,        UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
271*cdf0e10cSrcweir {/* 25 */    "TextConversion/IsDirectionToSimplified",        UPN_IS_DIRECTION_TO_SIMPLIFIED,            UPH_IS_DIRECTION_TO_SIMPLIFIED},
272*cdf0e10cSrcweir {/* 26 */    "TextConversion/IsUseCharacterVariants",         UPN_IS_USE_CHARACTER_VARIANTS,             UPH_IS_USE_CHARACTER_VARIANTS},
273*cdf0e10cSrcweir {/* 27 */    "TextConversion/IsTranslateCommonTerms",         UPN_IS_TRANSLATE_COMMON_TERMS,             UPH_IS_TRANSLATE_COMMON_TERMS},
274*cdf0e10cSrcweir {/* 28 */    "TextConversion/IsReverseMapping",               UPN_IS_REVERSE_MAPPING,                    UPH_IS_REVERSE_MAPPING},
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir {/* 29 */    "ServiceManager/DataFilesChangedCheckValue",     UPN_DATA_FILES_CHANGED_CHECK_VALUE,        UPH_DATA_FILES_CHANGED_CHECK_VALUE},
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir {/* 30 */    "GrammarChecking/IsAutoCheck",                   UPN_IS_GRAMMAR_AUTO,                      UPH_IS_GRAMMAR_AUTO},
279*cdf0e10cSrcweir {/* 31 */    "GrammarChecking/IsInteractiveCheck",            UPN_IS_GRAMMAR_INTERACTIVE,               UPH_IS_GRAMMAR_INTERACTIVE},
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir             /* similar to entry 0 (thus no own configuration entry) but with different property name and type */
282*cdf0e10cSrcweir {            NULL,											 UPN_DEFAULT_LANGUAGE,                      UPH_DEFAULT_LANGUAGE},
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir {            NULL,                                            NULL,                                      -1}
285*cdf0e10cSrcweir };
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir const uno::Sequence< OUString > & SvtLinguConfigItem::GetPropertyNames()
289*cdf0e10cSrcweir {
290*cdf0e10cSrcweir     static uno::Sequence< OUString > aNames;
291*cdf0e10cSrcweir 	static sal_Bool bInitialized = sal_False;
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 	if (!bInitialized)
294*cdf0e10cSrcweir 	{
295*cdf0e10cSrcweir 		sal_Int32 nMax = sizeof(aNamesToHdl) / sizeof(aNamesToHdl[0]);
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir 		aNames.realloc( nMax );
298*cdf0e10cSrcweir 		OUString *pNames = aNames.getArray();
299*cdf0e10cSrcweir 		sal_Int32 nIdx = 0;
300*cdf0e10cSrcweir 		for (sal_Int32 i = 0; i < nMax;  ++i)
301*cdf0e10cSrcweir 		{
302*cdf0e10cSrcweir 			const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName;
303*cdf0e10cSrcweir 			if (pFullPropName)
304*cdf0e10cSrcweir 				pNames[ nIdx++ ] = A2OU( pFullPropName );
305*cdf0e10cSrcweir 		}
306*cdf0e10cSrcweir 		aNames.realloc( nIdx );
307*cdf0e10cSrcweir 		bInitialized = sal_True;
308*cdf0e10cSrcweir 	}
309*cdf0e10cSrcweir 	return aNames;
310*cdf0e10cSrcweir }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::GetHdlByName(
314*cdf0e10cSrcweir 	sal_Int32 &rnHdl,
315*cdf0e10cSrcweir 	const OUString &rPropertyName,
316*cdf0e10cSrcweir 	sal_Bool bFullPropName )
317*cdf0e10cSrcweir {
318*cdf0e10cSrcweir     NamesToHdl *pEntry = &aNamesToHdl[0];
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir 	if (bFullPropName)
321*cdf0e10cSrcweir 	{
322*cdf0e10cSrcweir 		while (pEntry && pEntry->pFullPropName != NULL)
323*cdf0e10cSrcweir 		{
324*cdf0e10cSrcweir 			if (0 == rPropertyName.compareToAscii( pEntry->pFullPropName ))
325*cdf0e10cSrcweir 			{
326*cdf0e10cSrcweir 				rnHdl = pEntry->nHdl;
327*cdf0e10cSrcweir 				break;
328*cdf0e10cSrcweir 			}
329*cdf0e10cSrcweir 			++pEntry;
330*cdf0e10cSrcweir 		}
331*cdf0e10cSrcweir 		return pEntry && pEntry->pFullPropName != NULL;
332*cdf0e10cSrcweir 	}
333*cdf0e10cSrcweir 	else
334*cdf0e10cSrcweir 	{
335*cdf0e10cSrcweir 		while (pEntry && pEntry->pPropName != NULL)
336*cdf0e10cSrcweir 		{
337*cdf0e10cSrcweir 			if (0 == rPropertyName.compareToAscii( pEntry->pPropName ))
338*cdf0e10cSrcweir 			{
339*cdf0e10cSrcweir 				rnHdl = pEntry->nHdl;
340*cdf0e10cSrcweir 				break;
341*cdf0e10cSrcweir 			}
342*cdf0e10cSrcweir 			++pEntry;
343*cdf0e10cSrcweir 		}
344*cdf0e10cSrcweir 		return pEntry && pEntry->pPropName != NULL;
345*cdf0e10cSrcweir 	}
346*cdf0e10cSrcweir }
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const
350*cdf0e10cSrcweir {
351*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir     sal_Int32 nHdl;
354*cdf0e10cSrcweir     return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any();
355*cdf0e10cSrcweir }
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle ) const
359*cdf0e10cSrcweir {
360*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir     uno::Any aRes;
363*cdf0e10cSrcweir 
364*cdf0e10cSrcweir     const sal_Int16 *pnVal = 0;
365*cdf0e10cSrcweir     const sal_Bool  *pbVal = 0;
366*cdf0e10cSrcweir     const sal_Int32 *pnInt32Val = 0;
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir     const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
369*cdf0e10cSrcweir     switch (nPropertyHandle)
370*cdf0e10cSrcweir     {
371*cdf0e10cSrcweir         case UPH_IS_USE_DICTIONARY_LIST :   pbVal = &rOpt.bIsUseDictionaryList; break;
372*cdf0e10cSrcweir         case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters;   break;
373*cdf0e10cSrcweir         case UPH_IS_HYPH_AUTO :             pbVal = &rOpt.bIsHyphAuto;  break;
374*cdf0e10cSrcweir         case UPH_IS_HYPH_SPECIAL :          pbVal = &rOpt.bIsHyphSpecial;   break;
375*cdf0e10cSrcweir         case UPH_IS_SPELL_AUTO :            pbVal = &rOpt.bIsSpellAuto; break;
376*cdf0e10cSrcweir         case UPH_IS_SPELL_SPECIAL :         pbVal = &rOpt.bIsSpellSpecial;  break;
377*cdf0e10cSrcweir         case UPH_IS_WRAP_REVERSE :          pbVal = &rOpt.bIsSpellReverse;  break;
378*cdf0e10cSrcweir         case UPH_DEFAULT_LANGUAGE :         pnVal = &rOpt.nDefaultLanguage; break;
379*cdf0e10cSrcweir         case UPH_IS_SPELL_CAPITALIZATION :  pbVal = &rOpt.bIsSpellCapitalization;       break;
380*cdf0e10cSrcweir         case UPH_IS_SPELL_WITH_DIGITS :     pbVal = &rOpt.bIsSpellWithDigits;   break;
381*cdf0e10cSrcweir         case UPH_IS_SPELL_UPPER_CASE :      pbVal = &rOpt.bIsSpellUpperCase;        break;
382*cdf0e10cSrcweir         case UPH_HYPH_MIN_LEADING :         pnVal = &rOpt.nHyphMinLeading;      break;
383*cdf0e10cSrcweir         case UPH_HYPH_MIN_TRAILING :        pnVal = &rOpt.nHyphMinTrailing; break;
384*cdf0e10cSrcweir         case UPH_HYPH_MIN_WORD_LENGTH :     pnVal = &rOpt.nHyphMinWordLength;   break;
385*cdf0e10cSrcweir         case UPH_ACTIVE_DICTIONARIES :
386*cdf0e10cSrcweir         {
387*cdf0e10cSrcweir             aRes <<= rOpt.aActiveDics;
388*cdf0e10cSrcweir             break;
389*cdf0e10cSrcweir         }
390*cdf0e10cSrcweir         case UPH_ACTIVE_CONVERSION_DICTIONARIES :
391*cdf0e10cSrcweir         {
392*cdf0e10cSrcweir             aRes <<= rOpt.aActiveConvDics;
393*cdf0e10cSrcweir             break;
394*cdf0e10cSrcweir         }
395*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE :
396*cdf0e10cSrcweir         {
397*cdf0e10cSrcweir             lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage, false ) );
398*cdf0e10cSrcweir             aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
399*cdf0e10cSrcweir             break;
400*cdf0e10cSrcweir         }
401*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE_CJK :
402*cdf0e10cSrcweir         {
403*cdf0e10cSrcweir             lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CJK, false ) );
404*cdf0e10cSrcweir             aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
405*cdf0e10cSrcweir             break;
406*cdf0e10cSrcweir         }
407*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE_CTL :
408*cdf0e10cSrcweir         {
409*cdf0e10cSrcweir             lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CTL, false ) );
410*cdf0e10cSrcweir             aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
411*cdf0e10cSrcweir             break;
412*cdf0e10cSrcweir         }
413*cdf0e10cSrcweir         case UPH_IS_IGNORE_POST_POSITIONAL_WORD :       pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
414*cdf0e10cSrcweir         case UPH_IS_AUTO_CLOSE_DIALOG :                 pbVal = &rOpt.bIsAutoCloseDialog; break;
415*cdf0e10cSrcweir         case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :  pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
416*cdf0e10cSrcweir         case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :       pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
417*cdf0e10cSrcweir 
418*cdf0e10cSrcweir         case UPH_IS_DIRECTION_TO_SIMPLIFIED:            pbVal = &rOpt.bIsDirectionToSimplified; break;
419*cdf0e10cSrcweir         case UPH_IS_USE_CHARACTER_VARIANTS :            pbVal = &rOpt.bIsUseCharacterVariants; break;
420*cdf0e10cSrcweir         case UPH_IS_TRANSLATE_COMMON_TERMS :            pbVal = &rOpt.bIsTranslateCommonTerms; break;
421*cdf0e10cSrcweir         case UPH_IS_REVERSE_MAPPING :                   pbVal = &rOpt.bIsReverseMapping; break;
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir         case UPH_DATA_FILES_CHANGED_CHECK_VALUE :       pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
424*cdf0e10cSrcweir         case UPH_IS_GRAMMAR_AUTO:                       pbVal = &rOpt.bIsGrammarAuto; break;
425*cdf0e10cSrcweir         case UPH_IS_GRAMMAR_INTERACTIVE:                pbVal = &rOpt.bIsGrammarInteractive; break;
426*cdf0e10cSrcweir         default :
427*cdf0e10cSrcweir             DBG_ASSERT( 0, "unexpected property handle" );
428*cdf0e10cSrcweir     }
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir     if (pbVal)
431*cdf0e10cSrcweir         aRes <<= *pbVal;
432*cdf0e10cSrcweir     else if (pnVal)
433*cdf0e10cSrcweir         aRes <<= *pnVal;
434*cdf0e10cSrcweir     else if (pnInt32Val)
435*cdf0e10cSrcweir         aRes <<= *pnInt32Val;
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir     return aRes;
438*cdf0e10cSrcweir }
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
442*cdf0e10cSrcweir {
443*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir     sal_Bool bSucc = sal_False;
446*cdf0e10cSrcweir     sal_Int32 nHdl;
447*cdf0e10cSrcweir     if (GetHdlByName( nHdl, rPropertyName ))
448*cdf0e10cSrcweir         bSucc = SetProperty( nHdl, rValue );
449*cdf0e10cSrcweir     return bSucc;
450*cdf0e10cSrcweir }
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
454*cdf0e10cSrcweir {
455*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir     sal_Bool bSucc = sal_False;
458*cdf0e10cSrcweir     if (!rValue.hasValue())
459*cdf0e10cSrcweir         return bSucc;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir     sal_Bool bMod = sal_False;
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir     sal_Int16 *pnVal = 0;
464*cdf0e10cSrcweir     sal_Bool  *pbVal = 0;
465*cdf0e10cSrcweir     sal_Int32 *pnInt32Val = 0;
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir     SvtLinguOptions &rOpt = aOpt;
468*cdf0e10cSrcweir     switch (nPropertyHandle)
469*cdf0e10cSrcweir     {
470*cdf0e10cSrcweir         case UPH_IS_USE_DICTIONARY_LIST :   pbVal = &rOpt.bIsUseDictionaryList;    break;
471*cdf0e10cSrcweir         case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters;  break;
472*cdf0e10cSrcweir         case UPH_IS_HYPH_AUTO :             pbVal = &rOpt.bIsHyphAuto; break;
473*cdf0e10cSrcweir         case UPH_IS_HYPH_SPECIAL :          pbVal = &rOpt.bIsHyphSpecial;  break;
474*cdf0e10cSrcweir         case UPH_IS_SPELL_AUTO :            pbVal = &rOpt.bIsSpellAuto;    break;
475*cdf0e10cSrcweir         case UPH_IS_SPELL_SPECIAL :         pbVal = &rOpt.bIsSpellSpecial; break;
476*cdf0e10cSrcweir         case UPH_IS_WRAP_REVERSE :          pbVal = &rOpt.bIsSpellReverse; break;
477*cdf0e10cSrcweir         case UPH_DEFAULT_LANGUAGE :         pnVal = &rOpt.nDefaultLanguage;    break;
478*cdf0e10cSrcweir         case UPH_IS_SPELL_CAPITALIZATION :  pbVal = &rOpt.bIsSpellCapitalization;      break;
479*cdf0e10cSrcweir         case UPH_IS_SPELL_WITH_DIGITS :     pbVal = &rOpt.bIsSpellWithDigits;  break;
480*cdf0e10cSrcweir         case UPH_IS_SPELL_UPPER_CASE :      pbVal = &rOpt.bIsSpellUpperCase;       break;
481*cdf0e10cSrcweir         case UPH_HYPH_MIN_LEADING :         pnVal = &rOpt.nHyphMinLeading;     break;
482*cdf0e10cSrcweir         case UPH_HYPH_MIN_TRAILING :        pnVal = &rOpt.nHyphMinTrailing;    break;
483*cdf0e10cSrcweir         case UPH_HYPH_MIN_WORD_LENGTH :     pnVal = &rOpt.nHyphMinWordLength;  break;
484*cdf0e10cSrcweir         case UPH_ACTIVE_DICTIONARIES :
485*cdf0e10cSrcweir         {
486*cdf0e10cSrcweir             rValue >>= rOpt.aActiveDics;
487*cdf0e10cSrcweir             bMod = sal_True;
488*cdf0e10cSrcweir             break;
489*cdf0e10cSrcweir         }
490*cdf0e10cSrcweir         case UPH_ACTIVE_CONVERSION_DICTIONARIES :
491*cdf0e10cSrcweir         {
492*cdf0e10cSrcweir             rValue >>= rOpt.aActiveConvDics;
493*cdf0e10cSrcweir             bMod = sal_True;
494*cdf0e10cSrcweir             break;
495*cdf0e10cSrcweir         }
496*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE :
497*cdf0e10cSrcweir         {
498*cdf0e10cSrcweir             bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue );
499*cdf0e10cSrcweir             bMod = bSucc;
500*cdf0e10cSrcweir             break;
501*cdf0e10cSrcweir         }
502*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE_CJK :
503*cdf0e10cSrcweir         {
504*cdf0e10cSrcweir             bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue );
505*cdf0e10cSrcweir             bMod = bSucc;
506*cdf0e10cSrcweir             break;
507*cdf0e10cSrcweir         }
508*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE_CTL :
509*cdf0e10cSrcweir         {
510*cdf0e10cSrcweir             bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue );
511*cdf0e10cSrcweir             bMod = bSucc;
512*cdf0e10cSrcweir             break;
513*cdf0e10cSrcweir         }
514*cdf0e10cSrcweir         case UPH_IS_IGNORE_POST_POSITIONAL_WORD :       pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
515*cdf0e10cSrcweir         case UPH_IS_AUTO_CLOSE_DIALOG :                 pbVal = &rOpt.bIsAutoCloseDialog; break;
516*cdf0e10cSrcweir         case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :  pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
517*cdf0e10cSrcweir         case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :       pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir         case UPH_IS_DIRECTION_TO_SIMPLIFIED :           pbVal = &rOpt.bIsDirectionToSimplified; break;
520*cdf0e10cSrcweir         case UPH_IS_USE_CHARACTER_VARIANTS :            pbVal = &rOpt.bIsUseCharacterVariants; break;
521*cdf0e10cSrcweir         case UPH_IS_TRANSLATE_COMMON_TERMS :            pbVal = &rOpt.bIsTranslateCommonTerms; break;
522*cdf0e10cSrcweir         case UPH_IS_REVERSE_MAPPING :                   pbVal = &rOpt.bIsReverseMapping; break;
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir         case UPH_DATA_FILES_CHANGED_CHECK_VALUE :       pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
525*cdf0e10cSrcweir         case UPH_IS_GRAMMAR_AUTO:                       pbVal = &rOpt.bIsGrammarAuto; break;
526*cdf0e10cSrcweir         case UPH_IS_GRAMMAR_INTERACTIVE:                pbVal = &rOpt.bIsGrammarInteractive; break;
527*cdf0e10cSrcweir         default :
528*cdf0e10cSrcweir             DBG_ASSERT( 0, "unexpected property handle" );
529*cdf0e10cSrcweir     }
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir     if (pbVal)
532*cdf0e10cSrcweir     {
533*cdf0e10cSrcweir         sal_Bool bNew = sal_Bool();
534*cdf0e10cSrcweir         if (rValue >>= bNew)
535*cdf0e10cSrcweir         {
536*cdf0e10cSrcweir             if (bNew != *pbVal)
537*cdf0e10cSrcweir             {
538*cdf0e10cSrcweir                 *pbVal = bNew;
539*cdf0e10cSrcweir                 bMod = sal_True;
540*cdf0e10cSrcweir             }
541*cdf0e10cSrcweir             bSucc = sal_True;
542*cdf0e10cSrcweir         }
543*cdf0e10cSrcweir     }
544*cdf0e10cSrcweir     else if (pnVal)
545*cdf0e10cSrcweir     {
546*cdf0e10cSrcweir         sal_Int16 nNew = sal_Int16();
547*cdf0e10cSrcweir         if (rValue >>= nNew)
548*cdf0e10cSrcweir         {
549*cdf0e10cSrcweir             if (nNew != *pnVal)
550*cdf0e10cSrcweir             {
551*cdf0e10cSrcweir                 *pnVal = nNew;
552*cdf0e10cSrcweir                 bMod = sal_True;
553*cdf0e10cSrcweir             }
554*cdf0e10cSrcweir             bSucc = sal_True;
555*cdf0e10cSrcweir         }
556*cdf0e10cSrcweir     }
557*cdf0e10cSrcweir     else if (pnInt32Val)
558*cdf0e10cSrcweir     {
559*cdf0e10cSrcweir         sal_Int32 nNew = sal_Int32();
560*cdf0e10cSrcweir         if (rValue >>= nNew)
561*cdf0e10cSrcweir         {
562*cdf0e10cSrcweir             if (nNew != *pnInt32Val)
563*cdf0e10cSrcweir             {
564*cdf0e10cSrcweir                 *pnInt32Val = nNew;
565*cdf0e10cSrcweir                 bMod = sal_True;
566*cdf0e10cSrcweir             }
567*cdf0e10cSrcweir             bSucc = sal_True;
568*cdf0e10cSrcweir         }
569*cdf0e10cSrcweir     }
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir     if (bMod)
572*cdf0e10cSrcweir         SetModified();
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir 	NotifyListeners(0);
575*cdf0e10cSrcweir     return bSucc;
576*cdf0e10cSrcweir }
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::GetOptions( SvtLinguOptions &rOptions ) const
580*cdf0e10cSrcweir {
581*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir     rOptions = aOpt;
584*cdf0e10cSrcweir     return sal_True;
585*cdf0e10cSrcweir }
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::SetOptions( const SvtLinguOptions &rOptions )
589*cdf0e10cSrcweir {
590*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir     aOpt = rOptions;
593*cdf0e10cSrcweir     SetModified();
594*cdf0e10cSrcweir 	NotifyListeners(0);
595*cdf0e10cSrcweir     return sal_True;
596*cdf0e10cSrcweir }
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir 
599*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames )
600*cdf0e10cSrcweir {
601*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir     sal_Bool bRes = sal_False;
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir     const OUString *pProperyNames = rProperyNames.getConstArray();
606*cdf0e10cSrcweir     sal_Int32 nProps = rProperyNames.getLength();
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir     const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames );
609*cdf0e10cSrcweir     const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames );
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir     if (nProps  &&  aValues.getLength() == nProps &&  aROStates.getLength() == nProps)
612*cdf0e10cSrcweir     {
613*cdf0e10cSrcweir         SvtLinguOptions &rOpt = aOpt;
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir         const uno::Any *pValue = aValues.getConstArray();
616*cdf0e10cSrcweir         const sal_Bool *pROStates = aROStates.getConstArray();
617*cdf0e10cSrcweir         for (sal_Int32 i = 0;  i < nProps;  ++i)
618*cdf0e10cSrcweir         {
619*cdf0e10cSrcweir             const uno::Any &rVal = pValue[i];
620*cdf0e10cSrcweir             sal_Int32 nPropertyHandle;
621*cdf0e10cSrcweir             GetHdlByName( nPropertyHandle, pProperyNames[i], sal_True );
622*cdf0e10cSrcweir             switch ( nPropertyHandle )
623*cdf0e10cSrcweir             {
624*cdf0e10cSrcweir                 case UPH_DEFAULT_LOCALE :
625*cdf0e10cSrcweir                     { rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break;
626*cdf0e10cSrcweir                 case UPH_ACTIVE_DICTIONARIES :
627*cdf0e10cSrcweir                     { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics;   } break;
628*cdf0e10cSrcweir                 case UPH_IS_USE_DICTIONARY_LIST :
629*cdf0e10cSrcweir                     { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList;  } break;
630*cdf0e10cSrcweir                 case UPH_IS_IGNORE_CONTROL_CHARACTERS :
631*cdf0e10cSrcweir                     { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters;    } break;
632*cdf0e10cSrcweir                 case UPH_DEFAULT_LOCALE_CJK :
633*cdf0e10cSrcweir                     { rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal );    } break;
634*cdf0e10cSrcweir                 case UPH_DEFAULT_LOCALE_CTL :
635*cdf0e10cSrcweir                     { rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal );    } break;
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir                 case UPH_IS_SPELL_UPPER_CASE :
638*cdf0e10cSrcweir                     { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break;
639*cdf0e10cSrcweir                 case UPH_IS_SPELL_WITH_DIGITS :
640*cdf0e10cSrcweir                     { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits;    } break;
641*cdf0e10cSrcweir                 case UPH_IS_SPELL_CAPITALIZATION :
642*cdf0e10cSrcweir                     { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization;    } break;
643*cdf0e10cSrcweir                 case UPH_IS_SPELL_AUTO :
644*cdf0e10cSrcweir                     { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto;  } break;
645*cdf0e10cSrcweir                 case UPH_IS_SPELL_SPECIAL :
646*cdf0e10cSrcweir                     { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial;   } break;
647*cdf0e10cSrcweir                 case UPH_IS_WRAP_REVERSE :
648*cdf0e10cSrcweir                     { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse;   } break;
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir                 case UPH_HYPH_MIN_LEADING :
651*cdf0e10cSrcweir                     { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading;   } break;
652*cdf0e10cSrcweir                 case UPH_HYPH_MIN_TRAILING :
653*cdf0e10cSrcweir                     { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing;  } break;
654*cdf0e10cSrcweir                 case UPH_HYPH_MIN_WORD_LENGTH :
655*cdf0e10cSrcweir                     { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength;    } break;
656*cdf0e10cSrcweir                 case UPH_IS_HYPH_SPECIAL :
657*cdf0e10cSrcweir                     { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial;    } break;
658*cdf0e10cSrcweir                 case UPH_IS_HYPH_AUTO :
659*cdf0e10cSrcweir                     { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto;   } break;
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir                 case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics;   } break;
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir                 case UPH_IS_IGNORE_POST_POSITIONAL_WORD :
664*cdf0e10cSrcweir                     { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord;  } break;
665*cdf0e10cSrcweir                 case UPH_IS_AUTO_CLOSE_DIALOG :
666*cdf0e10cSrcweir                     { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog;  } break;
667*cdf0e10cSrcweir                 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :
668*cdf0e10cSrcweir                     { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst;  } break;
669*cdf0e10cSrcweir                 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :
670*cdf0e10cSrcweir                     { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries;  } break;
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir                 case UPH_IS_DIRECTION_TO_SIMPLIFIED :
673*cdf0e10cSrcweir                     { rOpt.bROIsDirectionToSimplified = pROStates[i];
674*cdf0e10cSrcweir                             if( ! (rVal >>= rOpt.bIsDirectionToSimplified) )
675*cdf0e10cSrcweir                             {
676*cdf0e10cSrcweir                                 //default is locale dependent:
677*cdf0e10cSrcweir                                 if(  rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_HONGKONG
678*cdf0e10cSrcweir                                   || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_MACAU
679*cdf0e10cSrcweir                                   || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_TRADITIONAL )
680*cdf0e10cSrcweir                                 {
681*cdf0e10cSrcweir                                     rOpt.bIsDirectionToSimplified = sal_False;
682*cdf0e10cSrcweir                                 }
683*cdf0e10cSrcweir                                 else
684*cdf0e10cSrcweir                                 {
685*cdf0e10cSrcweir                                     rOpt.bIsDirectionToSimplified = sal_True;
686*cdf0e10cSrcweir                                 }
687*cdf0e10cSrcweir                             }
688*cdf0e10cSrcweir                     } break;
689*cdf0e10cSrcweir                 case UPH_IS_USE_CHARACTER_VARIANTS :
690*cdf0e10cSrcweir                     { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants;  } break;
691*cdf0e10cSrcweir                 case UPH_IS_TRANSLATE_COMMON_TERMS :
692*cdf0e10cSrcweir                     { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms;  } break;
693*cdf0e10cSrcweir                 case UPH_IS_REVERSE_MAPPING :
694*cdf0e10cSrcweir                     { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping;  } break;
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir                 case UPH_DATA_FILES_CHANGED_CHECK_VALUE :
697*cdf0e10cSrcweir                     { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue;  } break;
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir                 case UPH_IS_GRAMMAR_AUTO:
700*cdf0e10cSrcweir                     { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; }
701*cdf0e10cSrcweir                 break;
702*cdf0e10cSrcweir                 case UPH_IS_GRAMMAR_INTERACTIVE:
703*cdf0e10cSrcweir                     { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; }
704*cdf0e10cSrcweir                 break;
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir                 default:
707*cdf0e10cSrcweir                     DBG_ASSERT( 0, "unexpected case" );
708*cdf0e10cSrcweir             }
709*cdf0e10cSrcweir         }
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir         bRes = sal_True;
712*cdf0e10cSrcweir     }
713*cdf0e10cSrcweir     DBG_ASSERT( bRes, "LoadOptions failed" );
714*cdf0e10cSrcweir 
715*cdf0e10cSrcweir     return bRes;
716*cdf0e10cSrcweir }
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames )
720*cdf0e10cSrcweir {
721*cdf0e10cSrcweir     if (!IsModified())
722*cdf0e10cSrcweir         return sal_True;
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
725*cdf0e10cSrcweir 
726*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
727*cdf0e10cSrcweir     const uno::Type &rBOOL     = ::getBooleanCppuType();
728*cdf0e10cSrcweir     const uno::Type &rINT16    = ::getCppuType( (sal_Int16 *) NULL );
729*cdf0e10cSrcweir     const uno::Type &rINT32    = ::getCppuType( (sal_Int32 *) NULL );
730*cdf0e10cSrcweir 
731*cdf0e10cSrcweir     sal_Int32 nProps = rProperyNames.getLength();
732*cdf0e10cSrcweir     uno::Sequence< uno::Any > aValues( nProps );
733*cdf0e10cSrcweir     uno::Any *pValue = aValues.getArray();
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir     if (nProps  &&  aValues.getLength() == nProps)
736*cdf0e10cSrcweir     {
737*cdf0e10cSrcweir         const SvtLinguOptions &rOpt = aOpt;
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir         OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) );
740*cdf0e10cSrcweir         *pValue++ = uno::makeAny( aTmp );                               //   0
741*cdf0e10cSrcweir         *pValue++ = uno::makeAny( rOpt.aActiveDics );                   //   1
742*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsUseDictionaryList, rBOOL );        //   2
743*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsIgnoreControlCharacters, rBOOL );  //   3
744*cdf0e10cSrcweir         aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK );
745*cdf0e10cSrcweir         *pValue++ = uno::makeAny( aTmp );                               //   5
746*cdf0e10cSrcweir         aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL );
747*cdf0e10cSrcweir         *pValue++ = uno::makeAny( aTmp );                               //   6
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsSpellUpperCase, rBOOL );          //   7
750*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsSpellWithDigits, rBOOL );         //   8
751*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsSpellCapitalization, rBOOL );     //   9
752*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsSpellAuto, rBOOL );               //  10
753*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsSpellSpecial, rBOOL );            //  11
754*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsSpellReverse, rBOOL );            //  14
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir         pValue++->setValue( &rOpt.nHyphMinLeading, rINT16 );           //  15
757*cdf0e10cSrcweir         pValue++->setValue( &rOpt.nHyphMinTrailing, rINT16 );          //  16
758*cdf0e10cSrcweir         pValue++->setValue( &rOpt.nHyphMinWordLength, rINT16 );        //  17
759*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsHyphSpecial, rBOOL );             //  18
760*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsHyphAuto, rBOOL );                //  19
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir         *pValue++ = uno::makeAny( rOpt.aActiveConvDics );               //   20
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsIgnorePostPositionalWord, rBOOL ); //  21
765*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsAutoCloseDialog, rBOOL );          //  22
766*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsShowEntriesRecentlyUsedFirst, rBOOL ); //  23
767*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsAutoReplaceUniqueEntries, rBOOL ); //  24
768*cdf0e10cSrcweir 
769*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsDirectionToSimplified, rBOOL ); //  25
770*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsUseCharacterVariants, rBOOL ); //  26
771*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsTranslateCommonTerms, rBOOL ); //  27
772*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsReverseMapping, rBOOL ); //  28
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir         pValue++->setValue( &rOpt.nDataFilesChangedCheckValue, rINT32 ); //  29
775*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsGrammarAuto, rBOOL ); //  30
776*cdf0e10cSrcweir         pValue++->setValue( &rOpt.bIsGrammarInteractive, rBOOL ); // 31
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir         bRet |= PutProperties( rProperyNames, aValues );
779*cdf0e10cSrcweir     }
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir     if (bRet)
782*cdf0e10cSrcweir         ClearModified();
783*cdf0e10cSrcweir 
784*cdf0e10cSrcweir     return bRet;
785*cdf0e10cSrcweir }
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::IsReadOnly( const rtl::OUString &rPropertyName ) const
788*cdf0e10cSrcweir {
789*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
790*cdf0e10cSrcweir 
791*cdf0e10cSrcweir     sal_Bool bReadOnly = sal_False;
792*cdf0e10cSrcweir     sal_Int32 nHdl;
793*cdf0e10cSrcweir     if (GetHdlByName( nHdl, rPropertyName ))
794*cdf0e10cSrcweir         bReadOnly = IsReadOnly( nHdl );
795*cdf0e10cSrcweir     return bReadOnly;
796*cdf0e10cSrcweir }
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir sal_Bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle ) const
799*cdf0e10cSrcweir {
800*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir     sal_Bool bReadOnly = sal_False;
803*cdf0e10cSrcweir 
804*cdf0e10cSrcweir     const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
805*cdf0e10cSrcweir     switch(nPropertyHandle)
806*cdf0e10cSrcweir     {
807*cdf0e10cSrcweir         case UPH_IS_USE_DICTIONARY_LIST         : bReadOnly = rOpt.bROIsUseDictionaryList      ; break;
808*cdf0e10cSrcweir         case UPH_IS_IGNORE_CONTROL_CHARACTERS   : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break;
809*cdf0e10cSrcweir         case UPH_IS_HYPH_AUTO                   : bReadOnly = rOpt.bROIsHyphAuto               ; break;
810*cdf0e10cSrcweir         case UPH_IS_HYPH_SPECIAL                : bReadOnly = rOpt.bROIsHyphSpecial            ; break;
811*cdf0e10cSrcweir         case UPH_IS_SPELL_AUTO                  : bReadOnly = rOpt.bROIsSpellAuto              ; break;
812*cdf0e10cSrcweir         case UPH_IS_SPELL_SPECIAL               : bReadOnly = rOpt.bROIsSpellSpecial           ; break;
813*cdf0e10cSrcweir         case UPH_IS_WRAP_REVERSE                : bReadOnly = rOpt.bROIsSpellReverse           ; break;
814*cdf0e10cSrcweir         case UPH_DEFAULT_LANGUAGE               : bReadOnly = rOpt.bRODefaultLanguage          ; break;
815*cdf0e10cSrcweir         case UPH_IS_SPELL_CAPITALIZATION        : bReadOnly = rOpt.bROIsSpellCapitalization    ; break;
816*cdf0e10cSrcweir         case UPH_IS_SPELL_WITH_DIGITS           : bReadOnly = rOpt.bROIsSpellWithDigits        ; break;
817*cdf0e10cSrcweir         case UPH_IS_SPELL_UPPER_CASE            : bReadOnly = rOpt.bROIsSpellUpperCase         ; break;
818*cdf0e10cSrcweir         case UPH_HYPH_MIN_LEADING               : bReadOnly = rOpt.bROHyphMinLeading           ; break;
819*cdf0e10cSrcweir         case UPH_HYPH_MIN_TRAILING              : bReadOnly = rOpt.bROHyphMinTrailing          ; break;
820*cdf0e10cSrcweir         case UPH_HYPH_MIN_WORD_LENGTH           : bReadOnly = rOpt.bROHyphMinWordLength        ; break;
821*cdf0e10cSrcweir         case UPH_ACTIVE_DICTIONARIES            : bReadOnly = rOpt.bROActiveDics               ; break;
822*cdf0e10cSrcweir         case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics           ; break;
823*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE                 : bReadOnly = rOpt.bRODefaultLanguage          ; break;
824*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE_CJK             : bReadOnly = rOpt.bRODefaultLanguage_CJK      ; break;
825*cdf0e10cSrcweir         case UPH_DEFAULT_LOCALE_CTL             : bReadOnly = rOpt.bRODefaultLanguage_CTL      ; break;
826*cdf0e10cSrcweir         case UPH_IS_IGNORE_POST_POSITIONAL_WORD :       bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break;
827*cdf0e10cSrcweir         case UPH_IS_AUTO_CLOSE_DIALOG :                 bReadOnly = rOpt.bROIsAutoCloseDialog; break;
828*cdf0e10cSrcweir         case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :  bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break;
829*cdf0e10cSrcweir         case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :       bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break;
830*cdf0e10cSrcweir         case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break;
831*cdf0e10cSrcweir         case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break;
832*cdf0e10cSrcweir         case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break;
833*cdf0e10cSrcweir         case UPH_IS_REVERSE_MAPPING :        bReadOnly = rOpt.bROIsReverseMapping; break;
834*cdf0e10cSrcweir         case UPH_DATA_FILES_CHANGED_CHECK_VALUE :       bReadOnly = rOpt.bRODataFilesChangedCheckValue; break;
835*cdf0e10cSrcweir         case UPH_IS_GRAMMAR_AUTO:                       bReadOnly = rOpt.bROIsGrammarAuto; break;
836*cdf0e10cSrcweir         case UPH_IS_GRAMMAR_INTERACTIVE:                bReadOnly = rOpt.bROIsGrammarInteractive; break;
837*cdf0e10cSrcweir         default :
838*cdf0e10cSrcweir             DBG_ASSERT( 0, "unexpected property handle" );
839*cdf0e10cSrcweir     }
840*cdf0e10cSrcweir     return bReadOnly;
841*cdf0e10cSrcweir }
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir static SvtLinguConfigItem *pCfgItem = 0;
846*cdf0e10cSrcweir static sal_Int32           nCfgItemRefCount = 0;
847*cdf0e10cSrcweir 
848*cdf0e10cSrcweir static const rtl::OUString aG_SupportedDictionaryFormats( A2OU("SupportedDictionaryFormats") );
849*cdf0e10cSrcweir static const rtl::OUString aG_Dictionaries( A2OU("Dictionaries") );
850*cdf0e10cSrcweir static const rtl::OUString aG_Locations( A2OU("Locations") );
851*cdf0e10cSrcweir static const rtl::OUString aG_Format( A2OU("Format") );
852*cdf0e10cSrcweir static const rtl::OUString aG_Locales( A2OU("Locales") );
853*cdf0e10cSrcweir static const rtl::OUString aG_DisabledDictionaries( A2OU("DisabledDictionaries") );
854*cdf0e10cSrcweir static const rtl::OUString aG_LastActiveDictionaries( A2OU("LastActiveDictionaries") );
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir SvtLinguConfig::SvtLinguConfig()
857*cdf0e10cSrcweir {
858*cdf0e10cSrcweir     // Global access, must be guarded (multithreading)
859*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
860*cdf0e10cSrcweir     ++nCfgItemRefCount;
861*cdf0e10cSrcweir }
862*cdf0e10cSrcweir 
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir SvtLinguConfig::~SvtLinguConfig()
865*cdf0e10cSrcweir {
866*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir     if (pCfgItem && pCfgItem->IsModified())
869*cdf0e10cSrcweir         pCfgItem->Commit();
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir     if (--nCfgItemRefCount <= 0)
872*cdf0e10cSrcweir     {
873*cdf0e10cSrcweir         if (pCfgItem)
874*cdf0e10cSrcweir             delete pCfgItem;
875*cdf0e10cSrcweir         pCfgItem = 0;
876*cdf0e10cSrcweir     }
877*cdf0e10cSrcweir }
878*cdf0e10cSrcweir 
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir SvtLinguConfigItem & SvtLinguConfig::GetConfigItem()
881*cdf0e10cSrcweir {
882*cdf0e10cSrcweir     // Global access, must be guarded (multithreading)
883*cdf0e10cSrcweir     osl::MutexGuard aGuard( GetOwnMutex() );
884*cdf0e10cSrcweir     if (!pCfgItem)
885*cdf0e10cSrcweir     {
886*cdf0e10cSrcweir         pCfgItem = new SvtLinguConfigItem;
887*cdf0e10cSrcweir         ItemHolder1::holdConfigItem(E_LINGUCFG);
888*cdf0e10cSrcweir     }
889*cdf0e10cSrcweir     return *pCfgItem;
890*cdf0e10cSrcweir }
891*cdf0e10cSrcweir 
892*cdf0e10cSrcweir 
893*cdf0e10cSrcweir uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode )
894*cdf0e10cSrcweir {
895*cdf0e10cSrcweir     return GetConfigItem().GetNodeNames( rNode );
896*cdf0e10cSrcweir }
897*cdf0e10cSrcweir 
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames )
900*cdf0e10cSrcweir {
901*cdf0e10cSrcweir     return GetConfigItem().GetProperties(rNames);
902*cdf0e10cSrcweir }
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir 
905*cdf0e10cSrcweir sal_Bool SvtLinguConfig::ReplaceSetProperties(
906*cdf0e10cSrcweir         const OUString &rNode, uno::Sequence< beans::PropertyValue > rValues )
907*cdf0e10cSrcweir {
908*cdf0e10cSrcweir     return GetConfigItem().ReplaceSetProperties( rNode, rValues );
909*cdf0e10cSrcweir }
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir 
912*cdf0e10cSrcweir uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const
913*cdf0e10cSrcweir {
914*cdf0e10cSrcweir     return GetConfigItem().GetProperty( rPropertyName );
915*cdf0e10cSrcweir }
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir uno::Any SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle ) const
919*cdf0e10cSrcweir {
920*cdf0e10cSrcweir     return GetConfigItem().GetProperty( nPropertyHandle );
921*cdf0e10cSrcweir }
922*cdf0e10cSrcweir 
923*cdf0e10cSrcweir 
924*cdf0e10cSrcweir sal_Bool SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
925*cdf0e10cSrcweir {
926*cdf0e10cSrcweir     return GetConfigItem().SetProperty( rPropertyName, rValue );
927*cdf0e10cSrcweir }
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir 
930*cdf0e10cSrcweir sal_Bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
931*cdf0e10cSrcweir {
932*cdf0e10cSrcweir     return GetConfigItem().SetProperty( nPropertyHandle, rValue );
933*cdf0e10cSrcweir }
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir sal_Bool SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const
937*cdf0e10cSrcweir {
938*cdf0e10cSrcweir     return GetConfigItem().GetOptions( rOptions );
939*cdf0e10cSrcweir }
940*cdf0e10cSrcweir 
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir sal_Bool SvtLinguConfig::SetOptions( const SvtLinguOptions &rOptions )
943*cdf0e10cSrcweir {
944*cdf0e10cSrcweir     return GetConfigItem().SetOptions( rOptions );
945*cdf0e10cSrcweir }
946*cdf0e10cSrcweir 
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir sal_Bool SvtLinguConfig::IsReadOnly( const rtl::OUString &rPropertyName ) const
949*cdf0e10cSrcweir {
950*cdf0e10cSrcweir     return GetConfigItem().IsReadOnly( rPropertyName );
951*cdf0e10cSrcweir }
952*cdf0e10cSrcweir 
953*cdf0e10cSrcweir sal_Bool SvtLinguConfig::IsReadOnly( sal_Int32 nPropertyHandle ) const
954*cdf0e10cSrcweir {
955*cdf0e10cSrcweir     return GetConfigItem().IsReadOnly( nPropertyHandle );
956*cdf0e10cSrcweir }
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir sal_Bool SvtLinguConfig::GetElementNamesFor(
959*cdf0e10cSrcweir      const rtl::OUString &rNodeName,
960*cdf0e10cSrcweir      uno::Sequence< rtl::OUString > &rElementNames ) const
961*cdf0e10cSrcweir {
962*cdf0e10cSrcweir     bool bSuccess = false;
963*cdf0e10cSrcweir     try
964*cdf0e10cSrcweir     {
965*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
966*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
967*cdf0e10cSrcweir         xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
968*cdf0e10cSrcweir         rElementNames = xNA->getElementNames();
969*cdf0e10cSrcweir         bSuccess = true;
970*cdf0e10cSrcweir     }
971*cdf0e10cSrcweir     catch (uno::Exception &)
972*cdf0e10cSrcweir     {
973*cdf0e10cSrcweir     }
974*cdf0e10cSrcweir     return bSuccess;
975*cdf0e10cSrcweir }
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir static uno::Reference< container::XNameAccess > GetOrCreateSetEntry_Impl(
978*cdf0e10cSrcweir     const uno::Reference< container::XNameAccess > &rxSetNameAccess,
979*cdf0e10cSrcweir     const rtl::OUString &rEntryName )
980*cdf0e10cSrcweir {
981*cdf0e10cSrcweir     uno::Reference< container::XNameAccess > xResult;
982*cdf0e10cSrcweir     try
983*cdf0e10cSrcweir     {
984*cdf0e10cSrcweir         if (!rxSetNameAccess->hasByName( rEntryName ))
985*cdf0e10cSrcweir         {
986*cdf0e10cSrcweir             uno::Reference< lang::XSingleServiceFactory > xFactory( rxSetNameAccess, uno::UNO_QUERY_THROW);
987*cdf0e10cSrcweir             uno::Reference< uno::XInterface > xNewEntry( xFactory->createInstance() );
988*cdf0e10cSrcweir             uno::Reference< container::XNameContainer > xNC( rxSetNameAccess, uno::UNO_QUERY_THROW );
989*cdf0e10cSrcweir             xNC->insertByName( rEntryName, makeAny( xNewEntry ) );
990*cdf0e10cSrcweir         }
991*cdf0e10cSrcweir         xResult.set( rxSetNameAccess->getByName( rEntryName ), uno::UNO_QUERY_THROW );
992*cdf0e10cSrcweir     }
993*cdf0e10cSrcweir     catch (uno::Exception &)
994*cdf0e10cSrcweir     {
995*cdf0e10cSrcweir     }
996*cdf0e10cSrcweir     return xResult;
997*cdf0e10cSrcweir }
998*cdf0e10cSrcweir 
999*cdf0e10cSrcweir sal_Bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
1000*cdf0e10cSrcweir     const rtl::OUString &rSetName,
1001*cdf0e10cSrcweir     const rtl::OUString &rSetEntry,
1002*cdf0e10cSrcweir     uno::Sequence< rtl::OUString > &rFormatList ) const
1003*cdf0e10cSrcweir {
1004*cdf0e10cSrcweir     if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0)
1005*cdf0e10cSrcweir         return sal_False;
1006*cdf0e10cSrcweir     bool bSuccess = false;
1007*cdf0e10cSrcweir     try
1008*cdf0e10cSrcweir     {
1009*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1010*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1011*cdf0e10cSrcweir         xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
1012*cdf0e10cSrcweir         xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
1013*cdf0e10cSrcweir         if (xNA->getByName( aG_SupportedDictionaryFormats ) >>= rFormatList)
1014*cdf0e10cSrcweir             bSuccess = true;
1015*cdf0e10cSrcweir         DBG_ASSERT( rFormatList.getLength(), "supported dictionary format list is empty" );
1016*cdf0e10cSrcweir     }
1017*cdf0e10cSrcweir     catch (uno::Exception &)
1018*cdf0e10cSrcweir     {
1019*cdf0e10cSrcweir     }
1020*cdf0e10cSrcweir     return bSuccess;
1021*cdf0e10cSrcweir }
1022*cdf0e10cSrcweir 
1023*cdf0e10cSrcweir void SvtLinguConfig::SetOrCreateSupportedDictionaryFormatsFor(
1024*cdf0e10cSrcweir     const rtl::OUString &rSetName,
1025*cdf0e10cSrcweir     const rtl::OUString &rSetEntry,
1026*cdf0e10cSrcweir     const uno::Sequence< rtl::OUString > &rFormatList  ) const
1027*cdf0e10cSrcweir {
1028*cdf0e10cSrcweir     if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0)
1029*cdf0e10cSrcweir         return;
1030*cdf0e10cSrcweir     try
1031*cdf0e10cSrcweir     {
1032*cdf0e10cSrcweir         DBG_ASSERT( rFormatList.getLength(), "applying empty format list. Really??" );
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir         uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
1035*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
1036*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1037*cdf0e10cSrcweir         xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
1038*cdf0e10cSrcweir         xNA = GetOrCreateSetEntry_Impl( xNA, rSetEntry );
1039*cdf0e10cSrcweir 
1040*cdf0e10cSrcweir         uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
1041*cdf0e10cSrcweir         xNR->replaceByName( aG_SupportedDictionaryFormats, uno::makeAny( rFormatList ) );
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir         xUpdateAccess->commitChanges();
1044*cdf0e10cSrcweir     }
1045*cdf0e10cSrcweir     catch (uno::Exception &)
1046*cdf0e10cSrcweir     {
1047*cdf0e10cSrcweir     }
1048*cdf0e10cSrcweir }
1049*cdf0e10cSrcweir 
1050*cdf0e10cSrcweir 
1051*cdf0e10cSrcweir static uno::WeakReference< util::XMacroExpander > aG_xMacroExpander;
1052*cdf0e10cSrcweir 
1053*cdf0e10cSrcweir static uno::Reference< util::XMacroExpander > lcl_GetMacroExpander()
1054*cdf0e10cSrcweir {
1055*cdf0e10cSrcweir     uno::Reference< util::XMacroExpander > xMacroExpander( aG_xMacroExpander );
1056*cdf0e10cSrcweir     if ( !xMacroExpander.is() )
1057*cdf0e10cSrcweir     {
1058*cdf0e10cSrcweir         if ( !xMacroExpander.is() )
1059*cdf0e10cSrcweir         {
1060*cdf0e10cSrcweir             uno::Reference< uno::XComponentContext > xContext;
1061*cdf0e10cSrcweir             uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
1062*cdf0e10cSrcweir             xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
1063*cdf0e10cSrcweir             if ( xContext.is() )
1064*cdf0e10cSrcweir             {
1065*cdf0e10cSrcweir                 aG_xMacroExpander =  uno::Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
1066*cdf0e10cSrcweir                                         OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
1067*cdf0e10cSrcweir                                         uno::UNO_QUERY );
1068*cdf0e10cSrcweir                 xMacroExpander = aG_xMacroExpander;
1069*cdf0e10cSrcweir             }
1070*cdf0e10cSrcweir         }
1071*cdf0e10cSrcweir     }
1072*cdf0e10cSrcweir 
1073*cdf0e10cSrcweir     return xMacroExpander;
1074*cdf0e10cSrcweir }
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir static bool lcl_GetFileUrlFromOrigin(
1078*cdf0e10cSrcweir     OUString /*out*/ &rFileUrl,
1079*cdf0e10cSrcweir     const OUString &rOrigin,
1080*cdf0e10cSrcweir     uno::Reference< util::XMacroExpander > &rxMacroExpander )
1081*cdf0e10cSrcweir {
1082*cdf0e10cSrcweir     bool bSuccess = false;
1083*cdf0e10cSrcweir     if (rOrigin.getLength() > 0 && rxMacroExpander.is())
1084*cdf0e10cSrcweir     {
1085*cdf0e10cSrcweir         rtl::OUString aURL( rOrigin );
1086*cdf0e10cSrcweir         if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
1087*cdf0e10cSrcweir             rxMacroExpander.is() )
1088*cdf0e10cSrcweir         {
1089*cdf0e10cSrcweir             // cut protocol
1090*cdf0e10cSrcweir             OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
1091*cdf0e10cSrcweir             // decode uric class chars
1092*cdf0e10cSrcweir             aMacro = Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
1093*cdf0e10cSrcweir             // expand macro string
1094*cdf0e10cSrcweir             aURL = rxMacroExpander->expandMacros( aMacro );
1095*cdf0e10cSrcweir 
1096*cdf0e10cSrcweir             bool bIsFileUrl = aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( FILE_PROTOCOL )) == 0;
1097*cdf0e10cSrcweir             if (bIsFileUrl)
1098*cdf0e10cSrcweir             {
1099*cdf0e10cSrcweir                 rFileUrl = aURL;
1100*cdf0e10cSrcweir                 bSuccess = true;
1101*cdf0e10cSrcweir             }
1102*cdf0e10cSrcweir             else
1103*cdf0e10cSrcweir             {
1104*cdf0e10cSrcweir                 DBG_ASSERT( bIsFileUrl, "not a file URL");
1105*cdf0e10cSrcweir             }
1106*cdf0e10cSrcweir         }
1107*cdf0e10cSrcweir         else
1108*cdf0e10cSrcweir         {
1109*cdf0e10cSrcweir             DBG_ASSERT( 0, "failed to get file URL" );
1110*cdf0e10cSrcweir         }
1111*cdf0e10cSrcweir     }
1112*cdf0e10cSrcweir     return bSuccess;
1113*cdf0e10cSrcweir }
1114*cdf0e10cSrcweir 
1115*cdf0e10cSrcweir 
1116*cdf0e10cSrcweir sal_Bool SvtLinguConfig::GetDictionaryEntry(
1117*cdf0e10cSrcweir     const rtl::OUString &rNodeName,
1118*cdf0e10cSrcweir     SvtLinguConfigDictionaryEntry &rDicEntry ) const
1119*cdf0e10cSrcweir {
1120*cdf0e10cSrcweir     if (rNodeName.getLength() == 0)
1121*cdf0e10cSrcweir         return sal_False;
1122*cdf0e10cSrcweir     bool bSuccess = false;
1123*cdf0e10cSrcweir     try
1124*cdf0e10cSrcweir     {
1125*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1126*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1127*cdf0e10cSrcweir         xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
1128*cdf0e10cSrcweir         xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
1129*cdf0e10cSrcweir 
1130*cdf0e10cSrcweir         // read group data...
1131*cdf0e10cSrcweir         uno::Sequence< rtl::OUString >	aLocations;
1132*cdf0e10cSrcweir         rtl::OUString					aFormatName;
1133*cdf0e10cSrcweir 		uno::Sequence< rtl::OUString >  aLocaleNames;
1134*cdf0e10cSrcweir         bSuccess =  (xNA->getByName( aG_Locations ) >>= aLocations)  &&
1135*cdf0e10cSrcweir                     (xNA->getByName( aG_Format )    >>= aFormatName) &&
1136*cdf0e10cSrcweir                     (xNA->getByName( aG_Locales )   >>= aLocaleNames);
1137*cdf0e10cSrcweir         DBG_ASSERT( aLocations.getLength(), "Dictionary locations not set" );
1138*cdf0e10cSrcweir         DBG_ASSERT( aFormatName.getLength(), "Dictionary format name not set" );
1139*cdf0e10cSrcweir         DBG_ASSERT( aLocaleNames.getLength(), "No locales set for the dictionary" );
1140*cdf0e10cSrcweir 
1141*cdf0e10cSrcweir         // if sucessful continue
1142*cdf0e10cSrcweir         if (bSuccess)
1143*cdf0e10cSrcweir         {
1144*cdf0e10cSrcweir             // get file URL's for the locations
1145*cdf0e10cSrcweir             uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
1146*cdf0e10cSrcweir             for (sal_Int32 i = 0;  i < aLocations.getLength();  ++i)
1147*cdf0e10cSrcweir             {
1148*cdf0e10cSrcweir                 rtl::OUString &rLocation = aLocations[i];
1149*cdf0e10cSrcweir                 if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation, xMacroExpander ))
1150*cdf0e10cSrcweir                     bSuccess = false;
1151*cdf0e10cSrcweir             }
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir             // if everything was fine return the result
1154*cdf0e10cSrcweir             if (bSuccess)
1155*cdf0e10cSrcweir             {
1156*cdf0e10cSrcweir                 rDicEntry.aLocations    = aLocations;
1157*cdf0e10cSrcweir                 rDicEntry.aFormatName   = aFormatName;
1158*cdf0e10cSrcweir                 rDicEntry.aLocaleNames  = aLocaleNames;
1159*cdf0e10cSrcweir             }
1160*cdf0e10cSrcweir         }
1161*cdf0e10cSrcweir     }
1162*cdf0e10cSrcweir     catch (uno::Exception &)
1163*cdf0e10cSrcweir     {
1164*cdf0e10cSrcweir     }
1165*cdf0e10cSrcweir     return bSuccess;
1166*cdf0e10cSrcweir }
1167*cdf0e10cSrcweir 
1168*cdf0e10cSrcweir void SvtLinguConfig::SetOrCreateDictionaryEntry(
1169*cdf0e10cSrcweir     const rtl::OUString &rNodeName,
1170*cdf0e10cSrcweir     const SvtLinguConfigDictionaryEntry &rDicEntry ) const
1171*cdf0e10cSrcweir {
1172*cdf0e10cSrcweir     if (rNodeName.getLength() == 0)
1173*cdf0e10cSrcweir         return;
1174*cdf0e10cSrcweir     try
1175*cdf0e10cSrcweir     {
1176*cdf0e10cSrcweir         uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
1177*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
1178*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1179*cdf0e10cSrcweir         xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
1180*cdf0e10cSrcweir         xNA = GetOrCreateSetEntry_Impl( xNA, rNodeName );
1181*cdf0e10cSrcweir 
1182*cdf0e10cSrcweir         DBG_ASSERT( rDicEntry.aLocations.getLength(), "Applying empty dictionary locations. Really correct??" );
1183*cdf0e10cSrcweir         DBG_ASSERT( rDicEntry.aFormatName.getLength(), "Applying empty dictionary format name. Really correct??" );
1184*cdf0e10cSrcweir         DBG_ASSERT( rDicEntry.aLocaleNames.getLength(), "Applying empty list of locales for the dictionary. Really correct??" );
1185*cdf0e10cSrcweir 
1186*cdf0e10cSrcweir         uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
1187*cdf0e10cSrcweir         xNR->replaceByName( aG_Locations, uno::makeAny( rDicEntry.aLocations ) );
1188*cdf0e10cSrcweir         xNR->replaceByName( aG_Format,    uno::makeAny( rDicEntry.aFormatName ) );
1189*cdf0e10cSrcweir         xNR->replaceByName( aG_Locales,   uno::makeAny( rDicEntry.aLocaleNames ) );
1190*cdf0e10cSrcweir 
1191*cdf0e10cSrcweir         xUpdateAccess->commitChanges();
1192*cdf0e10cSrcweir     }
1193*cdf0e10cSrcweir     catch (uno::Exception &)
1194*cdf0e10cSrcweir     {
1195*cdf0e10cSrcweir     }
1196*cdf0e10cSrcweir }
1197*cdf0e10cSrcweir 
1198*cdf0e10cSrcweir uno::Sequence< rtl::OUString > SvtLinguConfig::GetDisabledDictionaries() const
1199*cdf0e10cSrcweir {
1200*cdf0e10cSrcweir     uno::Sequence< rtl::OUString > aResult;
1201*cdf0e10cSrcweir     try
1202*cdf0e10cSrcweir     {
1203*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1204*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1205*cdf0e10cSrcweir         xNA->getByName( aG_DisabledDictionaries ) >>= aResult;
1206*cdf0e10cSrcweir     }
1207*cdf0e10cSrcweir     catch (uno::Exception &)
1208*cdf0e10cSrcweir     {
1209*cdf0e10cSrcweir     }
1210*cdf0e10cSrcweir     return aResult;
1211*cdf0e10cSrcweir }
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir void SvtLinguConfig::SetDisabledDictionaries(
1214*cdf0e10cSrcweir     const uno::Sequence< rtl::OUString > &rDictionaries ) const
1215*cdf0e10cSrcweir {
1216*cdf0e10cSrcweir     try
1217*cdf0e10cSrcweir     {
1218*cdf0e10cSrcweir         uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
1219*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
1220*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1221*cdf0e10cSrcweir         if (xNA->hasByName( aG_DisabledDictionaries ))
1222*cdf0e10cSrcweir         {
1223*cdf0e10cSrcweir             uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
1224*cdf0e10cSrcweir             xNR->replaceByName( aG_DisabledDictionaries, makeAny( rDictionaries ) );
1225*cdf0e10cSrcweir         }
1226*cdf0e10cSrcweir         else
1227*cdf0e10cSrcweir         {
1228*cdf0e10cSrcweir             uno::Reference< container::XNameContainer > xNC( xNA, uno::UNO_QUERY_THROW );
1229*cdf0e10cSrcweir             xNC->insertByName( aG_DisabledDictionaries, makeAny( rDictionaries ) );
1230*cdf0e10cSrcweir         }
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir         xUpdateAccess->commitChanges();
1233*cdf0e10cSrcweir     }
1234*cdf0e10cSrcweir     catch (uno::Exception &)
1235*cdf0e10cSrcweir     {
1236*cdf0e10cSrcweir     }
1237*cdf0e10cSrcweir }
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat(
1240*cdf0e10cSrcweir     const rtl::OUString &rFormatName )
1241*cdf0e10cSrcweir {
1242*cdf0e10cSrcweir     std::vector< SvtLinguConfigDictionaryEntry > aRes;
1243*cdf0e10cSrcweir     if (rFormatName.getLength() == 0)
1244*cdf0e10cSrcweir         return aRes;
1245*cdf0e10cSrcweir 
1246*cdf0e10cSrcweir     try
1247*cdf0e10cSrcweir     {
1248*cdf0e10cSrcweir         uno::Sequence< rtl::OUString > aElementNames;
1249*cdf0e10cSrcweir         GetElementNamesFor( aG_Dictionaries, aElementNames );
1250*cdf0e10cSrcweir         sal_Int32 nLen = aElementNames.getLength();
1251*cdf0e10cSrcweir         const rtl::OUString *pElementNames = aElementNames.getConstArray();
1252*cdf0e10cSrcweir 
1253*cdf0e10cSrcweir         SvtLinguConfigDictionaryEntry aDicEntry;
1254*cdf0e10cSrcweir         for (sal_Int32 i = 0;  i < nLen;  ++i)
1255*cdf0e10cSrcweir         {
1256*cdf0e10cSrcweir             // does dictionary match the format we are looking for?
1257*cdf0e10cSrcweir             if (GetDictionaryEntry( pElementNames[i], aDicEntry ) &&
1258*cdf0e10cSrcweir                 aDicEntry.aFormatName == rFormatName)
1259*cdf0e10cSrcweir             {
1260*cdf0e10cSrcweir                 // check if it is active or not
1261*cdf0e10cSrcweir                 bool bDicIsActive = true;
1262*cdf0e10cSrcweir                 const uno::Sequence< rtl::OUString > aDisabledDics( GetDisabledDictionaries() );
1263*cdf0e10cSrcweir                 for (sal_Int32 k = 0;  bDicIsActive && k < aDisabledDics.getLength();  ++k)
1264*cdf0e10cSrcweir                 {
1265*cdf0e10cSrcweir                     if (aDisabledDics[k] == pElementNames[i])
1266*cdf0e10cSrcweir                         bDicIsActive = false;
1267*cdf0e10cSrcweir                 }
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir                 if (bDicIsActive)
1270*cdf0e10cSrcweir                 {
1271*cdf0e10cSrcweir                     DBG_ASSERT( aDicEntry.aFormatName.getLength(),
1272*cdf0e10cSrcweir                             "FormatName not set" );
1273*cdf0e10cSrcweir                     DBG_ASSERT( aDicEntry.aLocations.getLength(),
1274*cdf0e10cSrcweir                             "Locations not set" );
1275*cdf0e10cSrcweir                     DBG_ASSERT( aDicEntry.aLocaleNames.getLength(),
1276*cdf0e10cSrcweir                             "Locales not set" );
1277*cdf0e10cSrcweir                     aRes.push_back( aDicEntry );
1278*cdf0e10cSrcweir                 }
1279*cdf0e10cSrcweir             }
1280*cdf0e10cSrcweir         }
1281*cdf0e10cSrcweir     }
1282*cdf0e10cSrcweir     catch (uno::Exception &)
1283*cdf0e10cSrcweir     {
1284*cdf0e10cSrcweir     }
1285*cdf0e10cSrcweir 
1286*cdf0e10cSrcweir     return aRes;
1287*cdf0e10cSrcweir }
1288*cdf0e10cSrcweir 
1289*cdf0e10cSrcweir 
1290*cdf0e10cSrcweir uno::Reference< util::XChangesBatch > SvtLinguConfig::GetMainUpdateAccess() const
1291*cdf0e10cSrcweir {
1292*cdf0e10cSrcweir     if (!m_xMainUpdateAccess.is())
1293*cdf0e10cSrcweir     {
1294*cdf0e10cSrcweir         try
1295*cdf0e10cSrcweir         {
1296*cdf0e10cSrcweir             // get configuration provider
1297*cdf0e10cSrcweir             uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider;
1298*cdf0e10cSrcweir             uno::Reference< lang::XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory();
1299*cdf0e10cSrcweir             if (xMgr.is())
1300*cdf0e10cSrcweir             {
1301*cdf0e10cSrcweir                 xConfigurationProvider = uno::Reference< lang::XMultiServiceFactory > (
1302*cdf0e10cSrcweir                         xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM(
1303*cdf0e10cSrcweir                             "com.sun.star.configuration.ConfigurationProvider" ) ) ),
1304*cdf0e10cSrcweir                         uno::UNO_QUERY_THROW ) ;
1305*cdf0e10cSrcweir             }
1306*cdf0e10cSrcweir 
1307*cdf0e10cSrcweir             // get configuration update access
1308*cdf0e10cSrcweir             beans::PropertyValue aValue;
1309*cdf0e10cSrcweir             aValue.Name  = A2OU( "nodepath" );
1310*cdf0e10cSrcweir             aValue.Value = uno::makeAny( A2OU("org.openoffice.Office.Linguistic") );
1311*cdf0e10cSrcweir             uno::Sequence< uno::Any > aProps(1);
1312*cdf0e10cSrcweir             aProps[0] <<= aValue;
1313*cdf0e10cSrcweir             m_xMainUpdateAccess = uno::Reference< util::XChangesBatch >(
1314*cdf0e10cSrcweir                     xConfigurationProvider->createInstanceWithArguments(
1315*cdf0e10cSrcweir                         A2OU( "com.sun.star.configuration.ConfigurationUpdateAccess" ), aProps ),
1316*cdf0e10cSrcweir                         uno::UNO_QUERY_THROW );
1317*cdf0e10cSrcweir         }
1318*cdf0e10cSrcweir         catch (uno::Exception &)
1319*cdf0e10cSrcweir         {
1320*cdf0e10cSrcweir         }
1321*cdf0e10cSrcweir     }
1322*cdf0e10cSrcweir 
1323*cdf0e10cSrcweir     return m_xMainUpdateAccess;
1324*cdf0e10cSrcweir }
1325*cdf0e10cSrcweir 
1326*cdf0e10cSrcweir 
1327*cdf0e10cSrcweir rtl::OUString SvtLinguConfig::GetVendorImageUrl_Impl(
1328*cdf0e10cSrcweir     const rtl::OUString &rServiceImplName,
1329*cdf0e10cSrcweir     const rtl::OUString &rImageName ) const
1330*cdf0e10cSrcweir {
1331*cdf0e10cSrcweir     rtl::OUString aRes;
1332*cdf0e10cSrcweir     try
1333*cdf0e10cSrcweir     {
1334*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1335*cdf0e10cSrcweir         xImagesNA.set( xImagesNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW );
1336*cdf0e10cSrcweir 
1337*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName( A2OU("ServiceNameEntries") ), uno::UNO_QUERY_THROW );
1338*cdf0e10cSrcweir         xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
1339*cdf0e10cSrcweir         uno::Any aAny( xNA->getByName( A2OU("VendorImagesNode") ) );
1340*cdf0e10cSrcweir         rtl::OUString aVendorImagesNode;
1341*cdf0e10cSrcweir         if (aAny >>= aVendorImagesNode)
1342*cdf0e10cSrcweir         {
1343*cdf0e10cSrcweir             xNA = xImagesNA;
1344*cdf0e10cSrcweir             xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW );
1345*cdf0e10cSrcweir             xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW );
1346*cdf0e10cSrcweir             aAny = xNA->getByName( rImageName );
1347*cdf0e10cSrcweir             rtl::OUString aTmp;
1348*cdf0e10cSrcweir             if (aAny >>= aTmp)
1349*cdf0e10cSrcweir             {
1350*cdf0e10cSrcweir                 uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
1351*cdf0e10cSrcweir                 if (lcl_GetFileUrlFromOrigin( aTmp, aTmp, xMacroExpander ))
1352*cdf0e10cSrcweir                     aRes = aTmp;
1353*cdf0e10cSrcweir             }
1354*cdf0e10cSrcweir         }
1355*cdf0e10cSrcweir     }
1356*cdf0e10cSrcweir     catch (uno::Exception &)
1357*cdf0e10cSrcweir     {
1358*cdf0e10cSrcweir         DBG_ASSERT( 0, "exception caught. GetVendorImageUrl_Impl failed" );
1359*cdf0e10cSrcweir     }
1360*cdf0e10cSrcweir     return aRes;
1361*cdf0e10cSrcweir }
1362*cdf0e10cSrcweir 
1363*cdf0e10cSrcweir 
1364*cdf0e10cSrcweir rtl::OUString SvtLinguConfig::GetSpellAndGrammarDialogImage(
1365*cdf0e10cSrcweir     const rtl::OUString &rServiceImplName,
1366*cdf0e10cSrcweir     bool bHighContrast ) const
1367*cdf0e10cSrcweir {
1368*cdf0e10cSrcweir     rtl::OUString   aRes;
1369*cdf0e10cSrcweir     if (rServiceImplName.getLength() > 0)
1370*cdf0e10cSrcweir     {
1371*cdf0e10cSrcweir         rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarDialogImage_HC" : "SpellAndGrammarDialogImage" ));
1372*cdf0e10cSrcweir         rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1373*cdf0e10cSrcweir         aRes = aPath;
1374*cdf0e10cSrcweir     }
1375*cdf0e10cSrcweir     return aRes;
1376*cdf0e10cSrcweir }
1377*cdf0e10cSrcweir 
1378*cdf0e10cSrcweir 
1379*cdf0e10cSrcweir rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
1380*cdf0e10cSrcweir     const rtl::OUString &rServiceImplName,
1381*cdf0e10cSrcweir     bool bHighContrast ) const
1382*cdf0e10cSrcweir {
1383*cdf0e10cSrcweir     rtl::OUString   aRes;
1384*cdf0e10cSrcweir     if (rServiceImplName.getLength() > 0)
1385*cdf0e10cSrcweir     {
1386*cdf0e10cSrcweir         rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuSuggestionImage_HC" : "SpellAndGrammarContextMenuSuggestionImage" ));
1387*cdf0e10cSrcweir         rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1388*cdf0e10cSrcweir         aRes = aPath;
1389*cdf0e10cSrcweir     }
1390*cdf0e10cSrcweir     return aRes;
1391*cdf0e10cSrcweir }
1392*cdf0e10cSrcweir 
1393*cdf0e10cSrcweir 
1394*cdf0e10cSrcweir rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
1395*cdf0e10cSrcweir     const rtl::OUString &rServiceImplName,
1396*cdf0e10cSrcweir     bool bHighContrast ) const
1397*cdf0e10cSrcweir {
1398*cdf0e10cSrcweir     rtl::OUString   aRes;
1399*cdf0e10cSrcweir     if (rServiceImplName.getLength() > 0)
1400*cdf0e10cSrcweir     {
1401*cdf0e10cSrcweir         rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuDictionaryImage_HC" : "SpellAndGrammarContextMenuDictionaryImage" ));
1402*cdf0e10cSrcweir         rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1403*cdf0e10cSrcweir         aRes = aPath;
1404*cdf0e10cSrcweir     }
1405*cdf0e10cSrcweir     return aRes;
1406*cdf0e10cSrcweir }
1407*cdf0e10cSrcweir 
1408*cdf0e10cSrcweir 
1409*cdf0e10cSrcweir ::rtl::OUString SvtLinguConfig::GetThesaurusDialogImage(
1410*cdf0e10cSrcweir     const ::rtl::OUString &rServiceImplName,
1411*cdf0e10cSrcweir     bool bHighContrast ) const
1412*cdf0e10cSrcweir {
1413*cdf0e10cSrcweir     rtl::OUString   aRes;
1414*cdf0e10cSrcweir     if (rServiceImplName.getLength() > 0)
1415*cdf0e10cSrcweir     {
1416*cdf0e10cSrcweir         rtl::OUString aImageName( A2OU( bHighContrast ? "ThesaurusDialogImage_HC" : "ThesaurusDialogImage" ));
1417*cdf0e10cSrcweir         rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1418*cdf0e10cSrcweir         aRes = aPath;
1419*cdf0e10cSrcweir     }
1420*cdf0e10cSrcweir     return aRes;
1421*cdf0e10cSrcweir }
1422*cdf0e10cSrcweir 
1423*cdf0e10cSrcweir 
1424*cdf0e10cSrcweir ::rtl::OUString SvtLinguConfig::GetSynonymsContextImage(
1425*cdf0e10cSrcweir     const ::rtl::OUString &rServiceImplName,
1426*cdf0e10cSrcweir     bool bHighContrast ) const
1427*cdf0e10cSrcweir {
1428*cdf0e10cSrcweir     rtl::OUString   aRes;
1429*cdf0e10cSrcweir     if (rServiceImplName.getLength() > 0)
1430*cdf0e10cSrcweir     {
1431*cdf0e10cSrcweir         rtl::OUString aImageName( A2OU( bHighContrast ? "SynonymsContextMenuImage_HC" : "SynonymsContextMenuImage" ));
1432*cdf0e10cSrcweir         rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1433*cdf0e10cSrcweir         aRes = aPath;
1434*cdf0e10cSrcweir     }
1435*cdf0e10cSrcweir     return aRes;
1436*cdf0e10cSrcweir }
1437*cdf0e10cSrcweir 
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir bool SvtLinguConfig::HasVendorImages( const char *pImageName ) const
1440*cdf0e10cSrcweir {
1441*cdf0e10cSrcweir     bool bRes = false;
1442*cdf0e10cSrcweir     if (pImageName)
1443*cdf0e10cSrcweir     {
1444*cdf0e10cSrcweir         try
1445*cdf0e10cSrcweir         {
1446*cdf0e10cSrcweir             uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1447*cdf0e10cSrcweir             xNA.set( xNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW );
1448*cdf0e10cSrcweir             xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW );
1449*cdf0e10cSrcweir 
1450*cdf0e10cSrcweir             uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() );
1451*cdf0e10cSrcweir             sal_Int32 nVendors = aElementNames.getLength();
1452*cdf0e10cSrcweir             const rtl::OUString *pVendor = aElementNames.getConstArray();
1453*cdf0e10cSrcweir             for (sal_Int32 i = 0;  i < nVendors;  ++i)
1454*cdf0e10cSrcweir             {
1455*cdf0e10cSrcweir                 uno::Reference< container::XNameAccess > xNA2( xNA->getByName( pVendor[i] ), uno::UNO_QUERY_THROW  );
1456*cdf0e10cSrcweir                 uno::Sequence< rtl::OUString > aPropNames( xNA2->getElementNames() );
1457*cdf0e10cSrcweir                 sal_Int32 nProps = aPropNames.getLength();
1458*cdf0e10cSrcweir                 const rtl::OUString *pPropNames = aPropNames.getConstArray();
1459*cdf0e10cSrcweir                 for (sal_Int32 k = 0;  k < nProps;  ++k)
1460*cdf0e10cSrcweir                 {
1461*cdf0e10cSrcweir                     // for a quicker check we ignore the HC image names here
1462*cdf0e10cSrcweir                     const OUString &rName = pPropNames[k];
1463*cdf0e10cSrcweir                     if (rName.equalsAscii( pImageName ))
1464*cdf0e10cSrcweir                     {
1465*cdf0e10cSrcweir                         bRes = true;
1466*cdf0e10cSrcweir                         break;
1467*cdf0e10cSrcweir                     }
1468*cdf0e10cSrcweir                 }
1469*cdf0e10cSrcweir             }
1470*cdf0e10cSrcweir         }
1471*cdf0e10cSrcweir         catch (uno::Exception &)
1472*cdf0e10cSrcweir         {
1473*cdf0e10cSrcweir             DBG_ASSERT( 0, "exception caught. HasVendorImages failed" );
1474*cdf0e10cSrcweir         }
1475*cdf0e10cSrcweir     }
1476*cdf0e10cSrcweir     return bRes;
1477*cdf0e10cSrcweir }
1478*cdf0e10cSrcweir 
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir bool SvtLinguConfig::HasGrammarChecker() const
1481*cdf0e10cSrcweir {
1482*cdf0e10cSrcweir 	bool bRes = false;
1483*cdf0e10cSrcweir 
1484*cdf0e10cSrcweir 	try
1485*cdf0e10cSrcweir 	{
1486*cdf0e10cSrcweir         uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1487*cdf0e10cSrcweir         xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1488*cdf0e10cSrcweir 		xNA.set( xNA->getByName( A2OU("GrammarCheckerList") ), uno::UNO_QUERY_THROW );
1489*cdf0e10cSrcweir 
1490*cdf0e10cSrcweir 		uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() );
1491*cdf0e10cSrcweir 		bRes = aElementNames.getLength() > 0;
1492*cdf0e10cSrcweir 	}
1493*cdf0e10cSrcweir 	catch (uno::Exception &)
1494*cdf0e10cSrcweir 	{
1495*cdf0e10cSrcweir 	}
1496*cdf0e10cSrcweir 
1497*cdf0e10cSrcweir     return bRes;
1498*cdf0e10cSrcweir }
1499*cdf0e10cSrcweir 
1500*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
1501*cdf0e10cSrcweir 
1502