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