LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/unotools/source/config - lingucfg.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 358 565 63.4 %
Date: 2013-07-09 Functions: 32 45 71.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10