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