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