Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/lang/Locale.hpp>
21 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
23 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
24 : #include <com/sun/star/container/XNameAccess.hpp>
25 : #include <com/sun/star/container/XNameContainer.hpp>
26 : #include <com/sun/star/container/XNameReplace.hpp>
27 : #include <com/sun/star/util/theMacroExpander.hpp>
28 : #include <rtl/uri.hxx>
29 : #include <rtl/instance.hxx>
30 : #include <osl/mutex.hxx>
31 : #include <i18nlangtag/mslangid.hxx>
32 : #include <i18nlangtag/languagetag.hxx>
33 : #include <tools/debug.hxx>
34 : #include <tools/string.hxx>
35 : #include <unotools/lingucfg.hxx>
36 : #include <unotools/linguprops.hxx>
37 : #include <sal/macros.h>
38 :
39 : #include <comphelper/processfactory.hxx>
40 :
41 : #include <itemholder1.hxx>
42 :
43 : using namespace com::sun::star;
44 :
45 : using ::rtl::Uri;
46 :
47 : #define EXPAND_PROTOCOL "vnd.sun.star.expand:"
48 : #define FILE_PROTOCOL "file:///"
49 :
50 : namespace
51 : {
52 : class theSvtLinguConfigItemMutex :
53 : public rtl::Static< osl::Mutex, theSvtLinguConfigItemMutex > {};
54 : }
55 :
56 6 : static sal_Bool lcl_SetLocale( sal_Int16 &rLanguage, const uno::Any &rVal )
57 : {
58 6 : sal_Bool bSucc = sal_False;
59 :
60 6 : lang::Locale aNew;
61 6 : if (rVal >>= aNew) // conversion successful?
62 : {
63 6 : sal_Int16 nNew = LanguageTag( aNew ).getLanguageType( false);
64 6 : if (nNew != rLanguage)
65 : {
66 6 : rLanguage = nNew;
67 6 : bSucc = sal_True;
68 : }
69 : }
70 6 : return bSucc;
71 : }
72 :
73 3 : static inline const OUString lcl_LanguageToCfgLocaleStr( sal_Int16 nLanguage )
74 : {
75 3 : OUString aRes;
76 3 : if (LANGUAGE_SYSTEM != nLanguage)
77 3 : aRes = LanguageTag( nLanguage ).getBcp47();
78 3 : return aRes;
79 : }
80 :
81 213 : static sal_Int16 lcl_CfgAnyToLanguage( const uno::Any &rVal )
82 : {
83 213 : OUString aTmp;
84 213 : rVal >>= aTmp;
85 213 : return (aTmp.isEmpty()) ? LANGUAGE_SYSTEM : LanguageTag( aTmp ).getLanguageType();
86 : }
87 :
88 15017 : SvtLinguOptions::SvtLinguOptions()
89 : {
90 15017 : nDefaultLanguage = LANGUAGE_NONE;
91 15017 : nDefaultLanguage_CJK = LANGUAGE_NONE;
92 15017 : nDefaultLanguage_CTL = LANGUAGE_NONE;
93 :
94 : // general options
95 : bIsUseDictionaryList =
96 15017 : bIsIgnoreControlCharacters = sal_True;
97 :
98 : // spelling options
99 : bIsSpellCapitalization =
100 15017 : bIsSpellSpecial = sal_True;
101 : bIsSpellAuto =
102 : bIsSpellReverse =
103 : bIsSpellWithDigits =
104 15017 : bIsSpellUpperCase = sal_False;
105 :
106 : // text conversion options
107 15017 : bIsIgnorePostPositionalWord = sal_True;
108 : bIsAutoCloseDialog =
109 : bIsShowEntriesRecentlyUsedFirst =
110 15017 : bIsAutoReplaceUniqueEntries = sal_False;
111 15017 : bIsDirectionToSimplified = sal_True;
112 : bIsUseCharacterVariants =
113 : bIsTranslateCommonTerms =
114 15017 : bIsReverseMapping = sal_False;
115 :
116 : bROIsDirectionToSimplified =
117 : bROIsUseCharacterVariants =
118 : bROIsTranslateCommonTerms =
119 15017 : bROIsReverseMapping = sal_False;
120 :
121 : // hyphenation options
122 15017 : bIsHyphSpecial = sal_True;
123 15017 : bIsHyphAuto = sal_False;
124 : nHyphMinLeading =
125 15017 : nHyphMinTrailing = 2;
126 15017 : nHyphMinWordLength = 0;
127 :
128 15017 : nDataFilesChangedCheckValue = 0;
129 :
130 : //grammar options
131 : bIsGrammarAuto = sal_False,
132 15017 : bIsGrammarInteractive = sal_False;
133 :
134 15017 : }
135 :
136 : class SvtLinguConfigItem : public utl::ConfigItem
137 : {
138 : SvtLinguOptions aOpt;
139 :
140 : // disallow copy-constructor and assignment-operator for now
141 : SvtLinguConfigItem( const SvtLinguConfigItem & );
142 : SvtLinguConfigItem & operator = ( const SvtLinguConfigItem & );
143 :
144 : static sal_Bool GetHdlByName( sal_Int32 &rnHdl, const OUString &rPropertyName, sal_Bool bFullPropName = sal_False );
145 : static const uno::Sequence< OUString > GetPropertyNames();
146 : sal_Bool LoadOptions( const uno::Sequence< OUString > &rProperyNames );
147 : sal_Bool SaveOptions( const uno::Sequence< OUString > &rProperyNames );
148 :
149 : public:
150 : SvtLinguConfigItem();
151 : virtual ~SvtLinguConfigItem();
152 :
153 : // utl::ConfigItem
154 : virtual void Notify( const com::sun::star::uno::Sequence< OUString > &rPropertyNames );
155 : virtual void Commit();
156 :
157 : // make some protected functions of utl::ConfigItem public
158 : using utl::ConfigItem::GetNodeNames;
159 : using utl::ConfigItem::GetProperties;
160 : //using utl::ConfigItem::PutProperties;
161 : //using utl::ConfigItem::SetSetProperties;
162 : using utl::ConfigItem::ReplaceSetProperties;
163 : //using utl::ConfigItem::GetReadOnlyStates;
164 :
165 :
166 : com::sun::star::uno::Any
167 : GetProperty( const OUString &rPropertyName ) const;
168 : com::sun::star::uno::Any
169 : GetProperty( sal_Int32 nPropertyHandle ) const;
170 :
171 : sal_Bool SetProperty( const OUString &rPropertyName,
172 : const com::sun::star::uno::Any &rValue );
173 : sal_Bool SetProperty( sal_Int32 nPropertyHandle,
174 : const com::sun::star::uno::Any &rValue );
175 :
176 : const SvtLinguOptions& GetOptions() const;
177 :
178 : sal_Bool IsReadOnly( const OUString &rPropertyName ) const;
179 : sal_Bool IsReadOnly( sal_Int32 nPropertyHandle ) const;
180 : };
181 :
182 :
183 71 : SvtLinguConfigItem::SvtLinguConfigItem() :
184 71 : utl::ConfigItem( OUString("Office.Linguistic") )
185 : {
186 71 : const uno::Sequence< OUString > &rPropertyNames = GetPropertyNames();
187 71 : LoadOptions( rPropertyNames );
188 71 : ClearModified();
189 :
190 : // request notify events when properties change
191 71 : EnableNotification( rPropertyNames );
192 71 : }
193 :
194 :
195 140 : SvtLinguConfigItem::~SvtLinguConfigItem()
196 : {
197 : //! Commit (SaveOptions) will be called by the d-tor of the base called !
198 140 : }
199 :
200 :
201 0 : void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames )
202 : {
203 0 : LoadOptions( rPropertyNames );
204 0 : NotifyListeners(0);
205 0 : }
206 :
207 :
208 1 : void SvtLinguConfigItem::Commit()
209 : {
210 1 : SaveOptions( GetPropertyNames() );
211 1 : }
212 :
213 :
214 : static struct NamesToHdl
215 : {
216 : const char *pFullPropName; // full qualified name as used in configuration
217 : const char *pPropName; // property name only (atom) of above
218 : sal_Int32 nHdl; // numeric handle representing the property
219 : }aNamesToHdl[] =
220 : {
221 : {/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE},
222 : {/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES},
223 : {/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST},
224 : {/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS},
225 : {/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK},
226 : {/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL},
227 :
228 : {/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE},
229 : {/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS},
230 : {/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION},
231 : {/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO},
232 : {/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL},
233 : {/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE},
234 :
235 : {/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING},
236 : {/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING},
237 : {/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH},
238 : {/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL},
239 : {/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO},
240 :
241 : {/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES},
242 : {/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD},
243 : {/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG},
244 : {/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
245 : {/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
246 : {/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED},
247 : {/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS},
248 : {/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS},
249 : {/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING},
250 :
251 : {/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE},
252 :
253 : {/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO},
254 : {/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE},
255 :
256 : /* similar to entry 0 (thus no own configuration entry) but with different property name and type */
257 : { NULL, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE},
258 :
259 : { NULL, NULL, -1}
260 : };
261 :
262 :
263 72 : const uno::Sequence< OUString > SvtLinguConfigItem::GetPropertyNames()
264 : {
265 72 : uno::Sequence< OUString > aNames;
266 :
267 72 : sal_Int32 nMax = SAL_N_ELEMENTS(aNamesToHdl);
268 :
269 72 : aNames.realloc( nMax );
270 72 : OUString *pNames = aNames.getArray();
271 72 : sal_Int32 nIdx = 0;
272 2304 : for (sal_Int32 i = 0; i < nMax; ++i)
273 : {
274 2232 : const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName;
275 2232 : if (pFullPropName)
276 2088 : pNames[ nIdx++ ] = OUString::createFromAscii( pFullPropName );
277 : }
278 72 : aNames.realloc( nIdx );
279 :
280 72 : return aNames;
281 : }
282 :
283 14636 : sal_Bool SvtLinguConfigItem::GetHdlByName(
284 : sal_Int32 &rnHdl,
285 : const OUString &rPropertyName,
286 : sal_Bool bFullPropName )
287 : {
288 14636 : NamesToHdl *pEntry = &aNamesToHdl[0];
289 :
290 14636 : if (bFullPropName)
291 : {
292 32944 : while (pEntry && pEntry->pFullPropName != NULL)
293 : {
294 30885 : if (0 == rPropertyName.compareToAscii( pEntry->pFullPropName ))
295 : {
296 2059 : rnHdl = pEntry->nHdl;
297 2059 : break;
298 : }
299 28826 : ++pEntry;
300 : }
301 2059 : return pEntry && pEntry->pFullPropName != NULL;
302 : }
303 : else
304 : {
305 361925 : while (pEntry && pEntry->pPropName != NULL)
306 : {
307 349348 : if (0 == rPropertyName.compareToAscii( pEntry->pPropName ))
308 : {
309 12577 : rnHdl = pEntry->nHdl;
310 12577 : break;
311 : }
312 336771 : ++pEntry;
313 : }
314 12577 : return pEntry && pEntry->pPropName != NULL;
315 : }
316 : }
317 :
318 :
319 12577 : uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const
320 : {
321 12577 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
322 :
323 : sal_Int32 nHdl;
324 12577 : return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any();
325 : }
326 :
327 :
328 79694 : uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle ) const
329 : {
330 79694 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
331 :
332 79694 : uno::Any aRes;
333 :
334 79694 : const sal_Int16 *pnVal = 0;
335 79694 : const sal_Bool *pbVal = 0;
336 79694 : const sal_Int32 *pnInt32Val = 0;
337 :
338 79694 : const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
339 79694 : switch (nPropertyHandle)
340 : {
341 33402 : case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
342 33403 : case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
343 13 : case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
344 13 : case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
345 13 : case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
346 25 : case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
347 31 : case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
348 13 : case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
349 32 : case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
350 32 : case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
351 32 : case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
352 20 : case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
353 20 : case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
354 20 : case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
355 : case UPH_ACTIVE_DICTIONARIES :
356 : {
357 0 : aRes <<= rOpt.aActiveDics;
358 0 : break;
359 : }
360 : case UPH_ACTIVE_CONVERSION_DICTIONARIES :
361 : {
362 0 : aRes <<= rOpt.aActiveConvDics;
363 0 : break;
364 : }
365 : case UPH_DEFAULT_LOCALE :
366 : {
367 52 : lang::Locale aLocale( LanguageTag( rOpt.nDefaultLanguage ).getLocale( false ) );
368 52 : aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
369 52 : break;
370 : }
371 : case UPH_DEFAULT_LOCALE_CJK :
372 : {
373 52 : lang::Locale aLocale( LanguageTag( rOpt.nDefaultLanguage_CJK ).getLocale( false ) );
374 52 : aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
375 52 : break;
376 : }
377 : case UPH_DEFAULT_LOCALE_CTL :
378 : {
379 52 : lang::Locale aLocale( LanguageTag( rOpt.nDefaultLanguage_CTL ).getLocale( false ) );
380 52 : aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
381 52 : break;
382 : }
383 0 : case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
384 0 : case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
385 0 : case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
386 0 : case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
387 :
388 0 : case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break;
389 0 : case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
390 0 : case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
391 0 : case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
392 :
393 0 : case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
394 12460 : case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
395 0 : case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
396 : default :
397 : DBG_ASSERT( 0, "unexpected property handle" );
398 : }
399 :
400 79694 : if (pbVal)
401 79456 : aRes <<= *pbVal;
402 238 : else if (pnVal)
403 73 : aRes <<= *pnVal;
404 165 : else if (pnInt32Val)
405 0 : aRes <<= *pnInt32Val;
406 :
407 79694 : return aRes;
408 : }
409 :
410 :
411 0 : sal_Bool SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
412 : {
413 0 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
414 :
415 0 : sal_Bool bSucc = sal_False;
416 : sal_Int32 nHdl;
417 0 : if (GetHdlByName( nHdl, rPropertyName ))
418 0 : bSucc = SetProperty( nHdl, rValue );
419 0 : return bSucc;
420 : }
421 :
422 :
423 63 : sal_Bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
424 : {
425 63 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
426 :
427 63 : sal_Bool bSucc = sal_False;
428 63 : if (!rValue.hasValue())
429 0 : return bSucc;
430 :
431 63 : sal_Bool bMod = sal_False;
432 :
433 63 : sal_Int16 *pnVal = 0;
434 63 : sal_Bool *pbVal = 0;
435 63 : sal_Int32 *pnInt32Val = 0;
436 :
437 63 : SvtLinguOptions &rOpt = aOpt;
438 63 : switch (nPropertyHandle)
439 : {
440 4 : case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
441 4 : case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
442 4 : case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
443 4 : case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
444 4 : case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
445 5 : case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
446 4 : case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
447 4 : case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
448 4 : case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
449 4 : case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
450 4 : case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
451 4 : case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
452 4 : case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
453 4 : case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
454 : case UPH_ACTIVE_DICTIONARIES :
455 : {
456 0 : rValue >>= rOpt.aActiveDics;
457 0 : bMod = sal_True;
458 0 : break;
459 : }
460 : case UPH_ACTIVE_CONVERSION_DICTIONARIES :
461 : {
462 0 : rValue >>= rOpt.aActiveConvDics;
463 0 : bMod = sal_True;
464 0 : break;
465 : }
466 : case UPH_DEFAULT_LOCALE :
467 : {
468 4 : bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue );
469 4 : bMod = bSucc;
470 4 : break;
471 : }
472 : case UPH_DEFAULT_LOCALE_CJK :
473 : {
474 1 : bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue );
475 1 : bMod = bSucc;
476 1 : break;
477 : }
478 : case UPH_DEFAULT_LOCALE_CTL :
479 : {
480 1 : bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue );
481 1 : bMod = bSucc;
482 1 : break;
483 : }
484 0 : case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
485 0 : case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
486 0 : case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
487 0 : case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
488 :
489 0 : case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break;
490 0 : case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
491 0 : case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
492 0 : case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
493 :
494 0 : case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
495 0 : case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
496 0 : case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
497 : default :
498 : DBG_ASSERT( 0, "unexpected property handle" );
499 : }
500 :
501 63 : if (pbVal)
502 : {
503 41 : sal_Bool bNew = sal_Bool();
504 41 : if (rValue >>= bNew)
505 : {
506 41 : if (bNew != *pbVal)
507 : {
508 41 : *pbVal = bNew;
509 41 : bMod = sal_True;
510 : }
511 41 : bSucc = sal_True;
512 : }
513 : }
514 22 : else if (pnVal)
515 : {
516 16 : sal_Int16 nNew = sal_Int16();
517 16 : if (rValue >>= nNew)
518 : {
519 16 : if (nNew != *pnVal)
520 : {
521 16 : *pnVal = nNew;
522 16 : bMod = sal_True;
523 : }
524 16 : bSucc = sal_True;
525 : }
526 : }
527 6 : else if (pnInt32Val)
528 : {
529 0 : sal_Int32 nNew = sal_Int32();
530 0 : if (rValue >>= nNew)
531 : {
532 0 : if (nNew != *pnInt32Val)
533 : {
534 0 : *pnInt32Val = nNew;
535 0 : bMod = sal_True;
536 : }
537 0 : bSucc = sal_True;
538 : }
539 : }
540 :
541 63 : if (bMod)
542 63 : SetModified();
543 :
544 63 : NotifyListeners(0);
545 63 : return bSucc;
546 : }
547 :
548 14841 : const SvtLinguOptions& SvtLinguConfigItem::GetOptions() const
549 : {
550 14841 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
551 14841 : return aOpt;
552 : }
553 :
554 71 : sal_Bool SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames )
555 : {
556 71 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
557 :
558 71 : sal_Bool bRes = sal_False;
559 :
560 71 : const OUString *pProperyNames = rProperyNames.getConstArray();
561 71 : sal_Int32 nProps = rProperyNames.getLength();
562 :
563 142 : const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames );
564 142 : const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames );
565 :
566 71 : if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps)
567 : {
568 71 : SvtLinguOptions &rOpt = aOpt;
569 :
570 71 : const uno::Any *pValue = aValues.getConstArray();
571 71 : const sal_Bool *pROStates = aROStates.getConstArray();
572 2130 : for (sal_Int32 i = 0; i < nProps; ++i)
573 : {
574 2059 : const uno::Any &rVal = pValue[i];
575 : sal_Int32 nPropertyHandle;
576 2059 : GetHdlByName( nPropertyHandle, pProperyNames[i], sal_True );
577 2059 : switch ( nPropertyHandle )
578 : {
579 : case UPH_DEFAULT_LOCALE :
580 71 : { rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break;
581 : case UPH_ACTIVE_DICTIONARIES :
582 71 : { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break;
583 : case UPH_IS_USE_DICTIONARY_LIST :
584 71 : { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break;
585 : case UPH_IS_IGNORE_CONTROL_CHARACTERS :
586 71 : { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break;
587 : case UPH_DEFAULT_LOCALE_CJK :
588 71 : { rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal ); } break;
589 : case UPH_DEFAULT_LOCALE_CTL :
590 71 : { rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal ); } break;
591 :
592 : case UPH_IS_SPELL_UPPER_CASE :
593 71 : { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break;
594 : case UPH_IS_SPELL_WITH_DIGITS :
595 71 : { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break;
596 : case UPH_IS_SPELL_CAPITALIZATION :
597 71 : { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break;
598 : case UPH_IS_SPELL_AUTO :
599 71 : { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break;
600 : case UPH_IS_SPELL_SPECIAL :
601 71 : { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break;
602 : case UPH_IS_WRAP_REVERSE :
603 71 : { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break;
604 :
605 : case UPH_HYPH_MIN_LEADING :
606 71 : { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break;
607 : case UPH_HYPH_MIN_TRAILING :
608 71 : { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break;
609 : case UPH_HYPH_MIN_WORD_LENGTH :
610 71 : { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break;
611 : case UPH_IS_HYPH_SPECIAL :
612 71 : { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break;
613 : case UPH_IS_HYPH_AUTO :
614 71 : { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break;
615 :
616 71 : case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break;
617 :
618 : case UPH_IS_IGNORE_POST_POSITIONAL_WORD :
619 71 : { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break;
620 : case UPH_IS_AUTO_CLOSE_DIALOG :
621 71 : { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break;
622 : case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :
623 71 : { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break;
624 : case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :
625 71 : { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break;
626 :
627 : case UPH_IS_DIRECTION_TO_SIMPLIFIED :
628 71 : { rOpt.bROIsDirectionToSimplified = pROStates[i];
629 71 : if( ! (rVal >>= rOpt.bIsDirectionToSimplified) )
630 : {
631 : //default is locale dependent:
632 71 : if (MsLangId::isTraditionalChinese(rOpt.nDefaultLanguage_CJK))
633 : {
634 0 : rOpt.bIsDirectionToSimplified = sal_False;
635 : }
636 : else
637 : {
638 71 : rOpt.bIsDirectionToSimplified = sal_True;
639 : }
640 : }
641 71 : } break;
642 : case UPH_IS_USE_CHARACTER_VARIANTS :
643 71 : { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break;
644 : case UPH_IS_TRANSLATE_COMMON_TERMS :
645 71 : { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break;
646 : case UPH_IS_REVERSE_MAPPING :
647 71 : { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break;
648 :
649 : case UPH_DATA_FILES_CHANGED_CHECK_VALUE :
650 71 : { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break;
651 :
652 : case UPH_IS_GRAMMAR_AUTO:
653 71 : { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; }
654 71 : break;
655 : case UPH_IS_GRAMMAR_INTERACTIVE:
656 71 : { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; }
657 71 : break;
658 :
659 : default:
660 : DBG_ASSERT( 0, "unexpected case" );
661 : }
662 : }
663 :
664 71 : bRes = sal_True;
665 : }
666 : DBG_ASSERT( bRes, "LoadOptions failed" );
667 :
668 142 : return bRes;
669 : }
670 :
671 :
672 1 : sal_Bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames )
673 : {
674 1 : if (!IsModified())
675 0 : return sal_True;
676 :
677 1 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
678 :
679 1 : sal_Bool bRet = sal_False;
680 1 : const uno::Type &rBOOL = ::getBooleanCppuType();
681 1 : const uno::Type &rINT16 = ::getCppuType( (sal_Int16 *) NULL );
682 1 : const uno::Type &rINT32 = ::getCppuType( (sal_Int32 *) NULL );
683 :
684 1 : sal_Int32 nProps = rProperyNames.getLength();
685 2 : uno::Sequence< uno::Any > aValues( nProps );
686 1 : uno::Any *pValue = aValues.getArray();
687 :
688 1 : if (nProps && aValues.getLength() == nProps)
689 : {
690 1 : const SvtLinguOptions &rOpt = aOpt;
691 :
692 1 : OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) );
693 1 : *pValue++ = uno::makeAny( aTmp ); // 0
694 1 : *pValue++ = uno::makeAny( rOpt.aActiveDics ); // 1
695 1 : pValue++->setValue( &rOpt.bIsUseDictionaryList, rBOOL ); // 2
696 1 : pValue++->setValue( &rOpt.bIsIgnoreControlCharacters, rBOOL ); // 3
697 1 : aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK );
698 1 : *pValue++ = uno::makeAny( aTmp ); // 5
699 1 : aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL );
700 1 : *pValue++ = uno::makeAny( aTmp ); // 6
701 :
702 1 : pValue++->setValue( &rOpt.bIsSpellUpperCase, rBOOL ); // 7
703 1 : pValue++->setValue( &rOpt.bIsSpellWithDigits, rBOOL ); // 8
704 1 : pValue++->setValue( &rOpt.bIsSpellCapitalization, rBOOL ); // 9
705 1 : pValue++->setValue( &rOpt.bIsSpellAuto, rBOOL ); // 10
706 1 : pValue++->setValue( &rOpt.bIsSpellSpecial, rBOOL ); // 11
707 1 : pValue++->setValue( &rOpt.bIsSpellReverse, rBOOL ); // 14
708 :
709 1 : pValue++->setValue( &rOpt.nHyphMinLeading, rINT16 ); // 15
710 1 : pValue++->setValue( &rOpt.nHyphMinTrailing, rINT16 ); // 16
711 1 : pValue++->setValue( &rOpt.nHyphMinWordLength, rINT16 ); // 17
712 1 : pValue++->setValue( &rOpt.bIsHyphSpecial, rBOOL ); // 18
713 1 : pValue++->setValue( &rOpt.bIsHyphAuto, rBOOL ); // 19
714 :
715 1 : *pValue++ = uno::makeAny( rOpt.aActiveConvDics ); // 20
716 :
717 1 : pValue++->setValue( &rOpt.bIsIgnorePostPositionalWord, rBOOL ); // 21
718 1 : pValue++->setValue( &rOpt.bIsAutoCloseDialog, rBOOL ); // 22
719 1 : pValue++->setValue( &rOpt.bIsShowEntriesRecentlyUsedFirst, rBOOL ); // 23
720 1 : pValue++->setValue( &rOpt.bIsAutoReplaceUniqueEntries, rBOOL ); // 24
721 :
722 1 : pValue++->setValue( &rOpt.bIsDirectionToSimplified, rBOOL ); // 25
723 1 : pValue++->setValue( &rOpt.bIsUseCharacterVariants, rBOOL ); // 26
724 1 : pValue++->setValue( &rOpt.bIsTranslateCommonTerms, rBOOL ); // 27
725 1 : pValue++->setValue( &rOpt.bIsReverseMapping, rBOOL ); // 28
726 :
727 1 : pValue++->setValue( &rOpt.nDataFilesChangedCheckValue, rINT32 ); // 29
728 1 : pValue++->setValue( &rOpt.bIsGrammarAuto, rBOOL ); // 30
729 1 : pValue++->setValue( &rOpt.bIsGrammarInteractive, rBOOL ); // 31
730 :
731 1 : bRet |= PutProperties( rProperyNames, aValues );
732 : }
733 :
734 1 : if (bRet)
735 1 : ClearModified();
736 :
737 2 : return bRet;
738 : }
739 :
740 0 : sal_Bool SvtLinguConfigItem::IsReadOnly( const OUString &rPropertyName ) const
741 : {
742 0 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
743 :
744 0 : sal_Bool bReadOnly = sal_False;
745 : sal_Int32 nHdl;
746 0 : if (GetHdlByName( nHdl, rPropertyName ))
747 0 : bReadOnly = IsReadOnly( nHdl );
748 0 : return bReadOnly;
749 : }
750 :
751 0 : sal_Bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle ) const
752 : {
753 0 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
754 :
755 0 : sal_Bool bReadOnly = sal_False;
756 :
757 0 : const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
758 0 : switch(nPropertyHandle)
759 : {
760 0 : case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList ; break;
761 0 : case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break;
762 0 : case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto ; break;
763 0 : case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial ; break;
764 0 : case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto ; break;
765 0 : case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial ; break;
766 0 : case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse ; break;
767 0 : case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage ; break;
768 0 : case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization ; break;
769 0 : case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits ; break;
770 0 : case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase ; break;
771 0 : case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading ; break;
772 0 : case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing ; break;
773 0 : case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength ; break;
774 0 : case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics ; break;
775 0 : case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics ; break;
776 0 : case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage ; break;
777 0 : case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK ; break;
778 0 : case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL ; break;
779 0 : case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break;
780 0 : case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break;
781 0 : case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break;
782 0 : case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break;
783 0 : case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break;
784 0 : case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break;
785 0 : case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break;
786 0 : case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break;
787 0 : case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break;
788 0 : case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break;
789 0 : case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break;
790 : default :
791 : DBG_ASSERT( 0, "unexpected property handle" );
792 : }
793 0 : return bReadOnly;
794 : }
795 :
796 : //////////////////////////////////////////////////////////////////////
797 :
798 : static SvtLinguConfigItem *pCfgItem = 0;
799 : static sal_Int32 nCfgItemRefCount = 0;
800 :
801 : static const char aG_SupportedDictionaryFormats[] = "SupportedDictionaryFormats";
802 : static const char aG_Dictionaries[] = "Dictionaries";
803 : static const char aG_Locations[] = "Locations";
804 : static const char aG_Format[] = "Format";
805 : static const char aG_Locales[] = "Locales";
806 : static const char aG_DisabledDictionaries[] = "DisabledDictionaries";
807 :
808 28569 : SvtLinguConfig::SvtLinguConfig()
809 : {
810 : // Global access, must be guarded (multithreading)
811 28569 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
812 28569 : ++nCfgItemRefCount;
813 28569 : }
814 :
815 57206 : SvtLinguConfig::~SvtLinguConfig()
816 : {
817 28568 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
818 :
819 28568 : if (pCfgItem && pCfgItem->IsModified())
820 0 : pCfgItem->Commit();
821 :
822 28568 : if (--nCfgItemRefCount <= 0)
823 : {
824 70 : if (pCfgItem)
825 70 : delete pCfgItem;
826 70 : pCfgItem = 0;
827 28568 : }
828 28638 : }
829 :
830 95741 : SvtLinguConfigItem & SvtLinguConfig::GetConfigItem()
831 : {
832 : // Global access, must be guarded (multithreading)
833 95741 : osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
834 95741 : if (!pCfgItem)
835 : {
836 71 : pCfgItem = new SvtLinguConfigItem;
837 71 : ItemHolder1::holdConfigItem(E_LINGUCFG);
838 : }
839 95741 : return *pCfgItem;
840 : }
841 :
842 647 : uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode )
843 : {
844 647 : return GetConfigItem().GetNodeNames( rNode );
845 : }
846 :
847 168 : uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames )
848 : {
849 168 : return GetConfigItem().GetProperties(rNames);
850 : }
851 :
852 328 : sal_Bool SvtLinguConfig::ReplaceSetProperties(
853 : const OUString &rNode, uno::Sequence< beans::PropertyValue > rValues )
854 : {
855 328 : return GetConfigItem().ReplaceSetProperties( rNode, rValues );
856 : }
857 :
858 12577 : uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const
859 : {
860 12577 : return GetConfigItem().GetProperty( rPropertyName );
861 : }
862 :
863 67117 : uno::Any SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle ) const
864 : {
865 67117 : return GetConfigItem().GetProperty( nPropertyHandle );
866 : }
867 :
868 0 : sal_Bool SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
869 : {
870 0 : return GetConfigItem().SetProperty( rPropertyName, rValue );
871 : }
872 :
873 63 : sal_Bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
874 : {
875 63 : return GetConfigItem().SetProperty( nPropertyHandle, rValue );
876 : }
877 :
878 14841 : sal_Bool SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const
879 : {
880 14841 : rOptions = GetConfigItem().GetOptions();
881 14841 : return sal_True;
882 : }
883 :
884 0 : sal_Bool SvtLinguConfig::IsReadOnly( const OUString &rPropertyName ) const
885 : {
886 0 : return GetConfigItem().IsReadOnly( rPropertyName );
887 : }
888 :
889 90 : sal_Bool SvtLinguConfig::GetElementNamesFor(
890 : const OUString &rNodeName,
891 : uno::Sequence< OUString > &rElementNames ) const
892 : {
893 90 : bool bSuccess = false;
894 : try
895 : {
896 90 : uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
897 90 : xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
898 90 : xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
899 90 : rElementNames = xNA->getElementNames();
900 90 : bSuccess = true;
901 : }
902 0 : catch (uno::Exception &)
903 : {
904 : }
905 90 : return bSuccess;
906 : }
907 :
908 90 : sal_Bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
909 : const OUString &rSetName,
910 : const OUString &rSetEntry,
911 : uno::Sequence< OUString > &rFormatList ) const
912 : {
913 90 : if (rSetName.isEmpty() || rSetEntry.isEmpty())
914 0 : return sal_False;
915 90 : bool bSuccess = false;
916 : try
917 : {
918 90 : uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
919 90 : xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
920 90 : xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
921 90 : xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
922 90 : if (xNA->getByName( OUString(aG_SupportedDictionaryFormats) ) >>= rFormatList)
923 90 : bSuccess = true;
924 90 : DBG_ASSERT( rFormatList.getLength(), "supported dictionary format list is empty" );
925 : }
926 0 : catch (uno::Exception &)
927 : {
928 : }
929 90 : return bSuccess;
930 : }
931 :
932 0 : static bool lcl_GetFileUrlFromOrigin(
933 : OUString /*out*/ &rFileUrl,
934 : const OUString &rOrigin )
935 : {
936 0 : bool bSuccess = false;
937 0 : if (!rOrigin.isEmpty())
938 : {
939 0 : OUString aURL( rOrigin );
940 0 : if ( aURL.startsWith( EXPAND_PROTOCOL ) )
941 : {
942 : // cut protocol
943 0 : OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
944 : // decode uric class chars
945 0 : aMacro = Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
946 : // expand macro string
947 0 : aURL = util::theMacroExpander::get(
948 0 : comphelper::getProcessComponentContext() )->expandMacros(
949 0 : aMacro );
950 :
951 0 : bool bIsFileUrl = aURL.startsWith( FILE_PROTOCOL );
952 0 : if (bIsFileUrl)
953 : {
954 0 : rFileUrl = aURL;
955 0 : bSuccess = true;
956 : }
957 : else
958 : {
959 : SAL_WARN(
960 : "unotools.config", "not a file URL, <" << aURL << ">" );
961 0 : }
962 : }
963 : else
964 : {
965 : SAL_WARN(
966 : "unotools.config", "failed to get file URL, <" << aURL << ">" );
967 0 : }
968 : }
969 0 : return bSuccess;
970 : }
971 :
972 :
973 0 : sal_Bool SvtLinguConfig::GetDictionaryEntry(
974 : const OUString &rNodeName,
975 : SvtLinguConfigDictionaryEntry &rDicEntry ) const
976 : {
977 0 : if (rNodeName.isEmpty())
978 0 : return sal_False;
979 0 : bool bSuccess = false;
980 : try
981 : {
982 0 : uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
983 0 : xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
984 0 : xNA.set( xNA->getByName(OUString(aG_Dictionaries)), uno::UNO_QUERY_THROW );
985 0 : xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
986 :
987 : // read group data...
988 0 : uno::Sequence< OUString > aLocations;
989 0 : OUString aFormatName;
990 0 : uno::Sequence< OUString > aLocaleNames;
991 0 : bSuccess = (xNA->getByName( OUString(aG_Locations) ) >>= aLocations) &&
992 0 : (xNA->getByName( OUString(aG_Format) ) >>= aFormatName) &&
993 0 : (xNA->getByName( OUString(aG_Locales) ) >>= aLocaleNames);
994 : DBG_ASSERT( aLocations.getLength(), "Dictionary locations not set" );
995 : DBG_ASSERT( !aFormatName.isEmpty(), "Dictionary format name not set" );
996 : DBG_ASSERT( aLocaleNames.getLength(), "No locales set for the dictionary" );
997 :
998 : // if sucessful continue
999 0 : if (bSuccess)
1000 : {
1001 : // get file URL's for the locations
1002 0 : for (sal_Int32 i = 0; i < aLocations.getLength(); ++i)
1003 : {
1004 0 : OUString &rLocation = aLocations[i];
1005 0 : if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation ))
1006 0 : bSuccess = false;
1007 : }
1008 :
1009 : // if everything was fine return the result
1010 0 : if (bSuccess)
1011 : {
1012 0 : rDicEntry.aLocations = aLocations;
1013 0 : rDicEntry.aFormatName = aFormatName;
1014 0 : rDicEntry.aLocaleNames = aLocaleNames;
1015 : }
1016 0 : }
1017 : }
1018 0 : catch (uno::Exception &)
1019 : {
1020 : }
1021 0 : return bSuccess;
1022 : }
1023 :
1024 0 : uno::Sequence< OUString > SvtLinguConfig::GetDisabledDictionaries() const
1025 : {
1026 0 : uno::Sequence< OUString > aResult;
1027 : try
1028 : {
1029 0 : uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1030 0 : xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
1031 0 : xNA->getByName( OUString(aG_DisabledDictionaries) ) >>= aResult;
1032 : }
1033 0 : catch (uno::Exception &)
1034 : {
1035 : }
1036 0 : return aResult;
1037 : }
1038 :
1039 90 : std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat(
1040 : const OUString &rFormatName )
1041 : {
1042 90 : std::vector< SvtLinguConfigDictionaryEntry > aRes;
1043 90 : if (rFormatName.isEmpty())
1044 0 : return aRes;
1045 :
1046 : try
1047 : {
1048 90 : uno::Sequence< OUString > aElementNames;
1049 90 : GetElementNamesFor( OUString(aG_Dictionaries), aElementNames );
1050 90 : sal_Int32 nLen = aElementNames.getLength();
1051 90 : const OUString *pElementNames = aElementNames.getConstArray();
1052 :
1053 180 : SvtLinguConfigDictionaryEntry aDicEntry;
1054 90 : for (sal_Int32 i = 0; i < nLen; ++i)
1055 : {
1056 : // does dictionary match the format we are looking for?
1057 0 : if (GetDictionaryEntry( pElementNames[i], aDicEntry ) &&
1058 0 : aDicEntry.aFormatName == rFormatName)
1059 : {
1060 : // check if it is active or not
1061 0 : bool bDicIsActive = true;
1062 0 : const uno::Sequence< OUString > aDisabledDics( GetDisabledDictionaries() );
1063 0 : for (sal_Int32 k = 0; bDicIsActive && k < aDisabledDics.getLength(); ++k)
1064 : {
1065 0 : if (aDisabledDics[k] == pElementNames[i])
1066 0 : bDicIsActive = false;
1067 : }
1068 :
1069 0 : if (bDicIsActive)
1070 : {
1071 : DBG_ASSERT( !aDicEntry.aFormatName.isEmpty(),
1072 : "FormatName not set" );
1073 : DBG_ASSERT( aDicEntry.aLocations.getLength(),
1074 : "Locations not set" );
1075 : DBG_ASSERT( aDicEntry.aLocaleNames.getLength(),
1076 : "Locales not set" );
1077 0 : aRes.push_back( aDicEntry );
1078 0 : }
1079 : }
1080 90 : }
1081 : }
1082 0 : catch (uno::Exception &)
1083 : {
1084 : }
1085 :
1086 90 : return aRes;
1087 : }
1088 :
1089 :
1090 1180 : uno::Reference< util::XChangesBatch > SvtLinguConfig::GetMainUpdateAccess() const
1091 : {
1092 1180 : if (!m_xMainUpdateAccess.is())
1093 : {
1094 : try
1095 : {
1096 : // get configuration provider
1097 1090 : uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
1098 : uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider =
1099 2180 : configuration::theDefaultProvider::get( xContext );
1100 :
1101 : // get configuration update access
1102 2180 : beans::PropertyValue aValue;
1103 1090 : aValue.Name = OUString("nodepath");
1104 1090 : aValue.Value = uno::makeAny(OUString("org.openoffice.Office.Linguistic"));
1105 2180 : uno::Sequence< uno::Any > aProps(1);
1106 1090 : aProps[0] <<= aValue;
1107 2180 : m_xMainUpdateAccess = uno::Reference< util::XChangesBatch >(
1108 1090 : xConfigurationProvider->createInstanceWithArguments(
1109 1090 : OUString("com.sun.star.configuration.ConfigurationUpdateAccess"), aProps),
1110 2180 : uno::UNO_QUERY_THROW );
1111 : }
1112 0 : catch (uno::Exception &)
1113 : {
1114 : }
1115 : }
1116 :
1117 1180 : return m_xMainUpdateAccess;
1118 : }
1119 :
1120 :
1121 0 : OUString SvtLinguConfig::GetVendorImageUrl_Impl(
1122 : const OUString &rServiceImplName,
1123 : const OUString &rImageName ) const
1124 : {
1125 0 : OUString aRes;
1126 : try
1127 : {
1128 0 : uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1129 0 : xImagesNA.set( xImagesNA->getByName("Images"), uno::UNO_QUERY_THROW );
1130 :
1131 0 : uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName("ServiceNameEntries"), uno::UNO_QUERY_THROW );
1132 0 : xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
1133 0 : uno::Any aAny(xNA->getByName("VendorImagesNode"));
1134 0 : OUString aVendorImagesNode;
1135 0 : if (aAny >>= aVendorImagesNode)
1136 : {
1137 0 : xNA = xImagesNA;
1138 0 : xNA.set( xNA->getByName("VendorImages"), uno::UNO_QUERY_THROW );
1139 0 : xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW );
1140 0 : aAny = xNA->getByName( rImageName );
1141 0 : OUString aTmp;
1142 0 : if (aAny >>= aTmp)
1143 : {
1144 0 : if (lcl_GetFileUrlFromOrigin( aTmp, aTmp ))
1145 0 : aRes = aTmp;
1146 0 : }
1147 0 : }
1148 : }
1149 0 : catch (uno::Exception &)
1150 : {
1151 : DBG_ASSERT( 0, "exception caught. GetVendorImageUrl_Impl failed" );
1152 : }
1153 0 : return aRes;
1154 : }
1155 :
1156 :
1157 0 : OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
1158 : const OUString &rServiceImplName
1159 : ) const
1160 : {
1161 0 : OUString aRes;
1162 0 : if (!rServiceImplName.isEmpty())
1163 : {
1164 0 : OUString aImageName( "SpellAndGrammarContextMenuSuggestionImage" );
1165 0 : OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1166 0 : aRes = aPath;
1167 : }
1168 0 : return aRes;
1169 : }
1170 :
1171 :
1172 0 : OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
1173 : const OUString &rServiceImplName
1174 : ) const
1175 : {
1176 0 : OUString aRes;
1177 0 : if (!rServiceImplName.isEmpty())
1178 : {
1179 0 : OUString aImageName( "SpellAndGrammarContextMenuDictionaryImage" );
1180 0 : OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1181 0 : aRes = aPath;
1182 : }
1183 0 : return aRes;
1184 : }
1185 :
1186 0 : OUString SvtLinguConfig::GetSynonymsContextImage(
1187 : const OUString &rServiceImplName
1188 : ) const
1189 : {
1190 0 : OUString aRes;
1191 0 : if (!rServiceImplName.isEmpty())
1192 : {
1193 0 : OUString aImageName( "SynonymsContextMenuImage" );
1194 0 : OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1195 0 : aRes = aPath;
1196 : }
1197 0 : return aRes;
1198 : }
1199 :
1200 1000 : bool SvtLinguConfig::HasGrammarChecker() const
1201 : {
1202 1000 : bool bRes = false;
1203 :
1204 : try
1205 : {
1206 1000 : uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1207 1000 : xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
1208 1000 : xNA.set( xNA->getByName("GrammarCheckerList"), uno::UNO_QUERY_THROW );
1209 :
1210 2000 : uno::Sequence< OUString > aElementNames( xNA->getElementNames() );
1211 2000 : bRes = aElementNames.getLength() > 0;
1212 : }
1213 0 : catch (const uno::Exception&)
1214 : {
1215 : }
1216 :
1217 1000 : return bRes;
1218 : }
1219 :
1220 : //////////////////////////////////////////////////////////////////////
1221 :
1222 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|