LCOV - code coverage report
Current view: top level - linguistic/source - misc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 159 344 46.2 %
Date: 2012-08-25 Functions: 27 41 65.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 169 548 30.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <sal/macros.h>
      30                 :            : #include <tools/string.hxx>
      31                 :            : #include <tools/fsys.hxx>
      32                 :            : #include <tools/debug.hxx>
      33                 :            : #include <unotools/pathoptions.hxx>
      34                 :            : #include <svl/lngmisc.hxx>
      35                 :            : #include <ucbhelper/content.hxx>
      36                 :            : #include <i18npool/mslangid.hxx>
      37                 :            : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      38                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      39                 :            : #include <com/sun/star/beans/XFastPropertySet.hpp>
      40                 :            : #include <com/sun/star/beans/XPropertyChangeListener.hpp>
      41                 :            : #include <com/sun/star/frame/XTerminateListener.hpp>
      42                 :            : #include <com/sun/star/frame/XDesktop.hpp>
      43                 :            : #include <com/sun/star/frame/XStorable.hpp>
      44                 :            : 
      45                 :            : #include <com/sun/star/beans/PropertyValues.hpp>
      46                 :            : #include <com/sun/star/uno/Sequence.hxx>
      47                 :            : #include <com/sun/star/uno/Reference.h>
      48                 :            : #include <com/sun/star/linguistic2/DictionaryType.hpp>
      49                 :            : #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
      50                 :            : #include <comphelper/processfactory.hxx>
      51                 :            : #include <unotools/localedatawrapper.hxx>
      52                 :            : #include <unotools/syslocale.hxx>
      53                 :            : 
      54                 :            : #include <rtl/instance.hxx>
      55                 :            : 
      56                 :            : #include "linguistic/misc.hxx"
      57                 :            : #include "defs.hxx"
      58                 :            : #include "linguistic/lngprops.hxx"
      59                 :            : #include "linguistic/hyphdta.hxx"
      60                 :            : #include <i18npool/mslangid.hxx>
      61                 :            : 
      62                 :            : using namespace osl;
      63                 :            : using namespace com::sun::star;
      64                 :            : using namespace com::sun::star::beans;
      65                 :            : using namespace com::sun::star::lang;
      66                 :            : using namespace com::sun::star::uno;
      67                 :            : using namespace com::sun::star::i18n;
      68                 :            : using namespace com::sun::star::linguistic2;
      69                 :            : 
      70                 :            : using ::rtl::OUString;
      71                 :            : 
      72                 :            : namespace linguistic
      73                 :            : {
      74                 :            : 
      75                 :            : 
      76                 :            : //!! multi-thread safe mutex for all platforms !!
      77                 :            : struct LinguMutex : public rtl::Static< osl::Mutex, LinguMutex >
      78                 :            : {
      79                 :            : };
      80                 :            : 
      81                 :    5174902 : osl::Mutex &    GetLinguMutex()
      82                 :            : {
      83                 :    5174902 :     return LinguMutex::get();
      84                 :            : }
      85                 :            : 
      86                 :            : 
      87                 :      66114 : LocaleDataWrapper & GetLocaleDataWrapper( sal_Int16 nLang )
      88                 :            : {
      89                 :            :     static LocaleDataWrapper aLclDtaWrp(
      90                 :            :                 comphelper::getProcessServiceFactory(),
      91 [ +  + ][ +  - ]:      66114 :                 CreateLocale( SvtSysLocale().GetUILanguage() ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ #  # ]
      92                 :            : 
      93         [ +  - ]:      66114 :     const Locale &rLcl = aLclDtaWrp.getLoadedLocale();
      94         [ +  - ]:      66114 :     Locale aLcl( CreateLocale( nLang ) );
      95   [ +  -  +  -  :     198342 :     if (aLcl.Language != rLcl.Language ||
           -  + ][ -  + ]
      96                 :      66114 :         aLcl.Country  != rLcl.Country  ||
      97                 :      66114 :         aLcl.Variant  != rLcl.Variant)
      98         [ #  # ]:          0 :         aLclDtaWrp.setLocale( aLcl );
      99                 :      66114 :     return aLclDtaWrp;
     100                 :            : }
     101                 :            : 
     102                 :          0 : static inline sal_Int32 Minimum( sal_Int32 n1, sal_Int32 n2, sal_Int32 n3 )
     103                 :            : {
     104         [ #  # ]:          0 :     sal_Int32 nMin = n1 < n2 ? n1 : n2;
     105         [ #  # ]:          0 :     return nMin < n3 ? nMin : n3;
     106                 :            : }
     107                 :            : 
     108                 :            : class IntArray2D
     109                 :            : {
     110                 :            : private:
     111                 :            :     sal_Int32  *pData;
     112                 :            :     int         n1, n2;
     113                 :            : 
     114                 :            : public:
     115                 :            :     IntArray2D( int nDim1, int nDim2 );
     116                 :            :     ~IntArray2D();
     117                 :            : 
     118                 :            :     sal_Int32 & Value( int i, int k  );
     119                 :            : };
     120                 :            : 
     121                 :          0 : IntArray2D::IntArray2D( int nDim1, int nDim2 )
     122                 :            : {
     123                 :          0 :     n1 = nDim1;
     124                 :          0 :     n2 = nDim2;
     125                 :          0 :     pData = new sal_Int32[n1 * n2];
     126                 :          0 : }
     127                 :            : 
     128                 :          0 : IntArray2D::~IntArray2D()
     129                 :            : {
     130         [ #  # ]:          0 :     delete[] pData;
     131                 :          0 : }
     132                 :            : 
     133                 :          0 : sal_Int32 & IntArray2D::Value( int i, int k  )
     134                 :            : {
     135                 :            :     DBG_ASSERT( 0 <= i && i < n1, "first index out of range" );
     136                 :            :     DBG_ASSERT( 0 <= k && k < n2, "first index out of range" );
     137                 :            :     DBG_ASSERT( i * n2 + k < n1 * n2, "index out of range" );
     138                 :          0 :     return pData[ i * n2 + k ];
     139                 :            : }
     140                 :            : 
     141                 :            : 
     142                 :          0 : sal_Int32 LevDistance( const OUString &rTxt1, const OUString &rTxt2 )
     143                 :            : {
     144                 :          0 :     sal_Int32 nLen1 = rTxt1.getLength();
     145                 :          0 :     sal_Int32 nLen2 = rTxt2.getLength();
     146                 :            : 
     147         [ #  # ]:          0 :     if (nLen1 == 0)
     148                 :          0 :         return nLen2;
     149         [ #  # ]:          0 :     if (nLen2 == 0)
     150                 :          0 :         return nLen1;
     151                 :            : 
     152         [ #  # ]:          0 :     IntArray2D aData( nLen1 + 1, nLen2 + 1 );
     153                 :            : 
     154                 :            :     sal_Int32 i, k;
     155         [ #  # ]:          0 :     for (i = 0;  i <= nLen1;  ++i)
     156                 :          0 :         aData.Value(i, 0) = i;
     157         [ #  # ]:          0 :     for (k = 0;  k <= nLen2;  ++k)
     158                 :          0 :         aData.Value(0, k) = k;
     159         [ #  # ]:          0 :     for (i = 1;  i <= nLen1;  ++i)
     160                 :            :     {
     161         [ #  # ]:          0 :         for (k = 1;  k <= nLen2;  ++k)
     162                 :            :         {
     163                 :          0 :             sal_Unicode c1i = rTxt1.getStr()[i - 1];
     164                 :          0 :             sal_Unicode c2k = rTxt2.getStr()[k - 1];
     165                 :          0 :             sal_Int32 nCost = c1i == c2k ? 0 : 1;
     166                 :          0 :             sal_Int32 nNew = Minimum( aData.Value(i-1, k  ) + 1,
     167                 :          0 :                                        aData.Value(i  , k-1) + 1,
     168                 :          0 :                                        aData.Value(i-1, k-1) + nCost );
     169                 :            :             // take transposition (exchange with left or right char) in account
     170 [ #  # ][ #  # ]:          0 :             if (2 < i && 2 < k)
     171                 :            :             {
     172                 :          0 :                 int nT = aData.Value(i-2, k-2) + 1;
     173         [ #  # ]:          0 :                 if (rTxt1.getStr()[i - 2] != c1i)
     174                 :          0 :                     ++nT;
     175         [ #  # ]:          0 :                 if (rTxt2.getStr()[k - 2] != c2k)
     176                 :          0 :                     ++nT;
     177         [ #  # ]:          0 :                 if (nT < nNew)
     178                 :          0 :                     nNew = nT;
     179                 :            :             }
     180                 :            : 
     181                 :          0 :             aData.Value(i, k) = nNew;
     182                 :            :         }
     183                 :            :     }
     184                 :          0 :     sal_Int32 nDist = aData.Value(nLen1, nLen2);
     185                 :          0 :     return nDist;
     186                 :            :  }
     187                 :            : 
     188                 :            : 
     189                 :      65832 : sal_Bool IsUseDicList( const PropertyValues &rProperties,
     190                 :            :         const uno::Reference< XPropertySet > &rxProp )
     191                 :            : {
     192                 :      65832 :     sal_Bool bRes = sal_True;
     193                 :            : 
     194                 :      65832 :     sal_Int32 nLen = rProperties.getLength();
     195                 :      65832 :     const PropertyValue *pVal = rProperties.getConstArray();
     196                 :            :     sal_Int32 i;
     197                 :            : 
     198         [ -  + ]:      65832 :     for ( i = 0;  i < nLen;  ++i)
     199                 :            :     {
     200         [ #  # ]:          0 :         if (UPH_IS_USE_DICTIONARY_LIST == pVal[i].Handle)
     201                 :            :         {
     202                 :          0 :             pVal[i].Value >>= bRes;
     203                 :          0 :             break;
     204                 :            :         }
     205                 :            :     }
     206         [ +  - ]:      65832 :     if (i >= nLen)  // no temporary value found in 'rProperties'
     207                 :            :     {
     208         [ +  - ]:      65832 :         uno::Reference< XFastPropertySet > xFast( rxProp, UNO_QUERY );
     209         [ +  - ]:      65832 :         if (xFast.is())
     210 [ +  - ][ +  - ]:      65832 :             xFast->getFastPropertyValue( UPH_IS_USE_DICTIONARY_LIST ) >>= bRes;
     211                 :            :     }
     212                 :            : 
     213                 :      65832 :     return bRes;
     214                 :            : }
     215                 :            : 
     216                 :            : 
     217                 :      65832 : sal_Bool IsIgnoreControlChars( const PropertyValues &rProperties,
     218                 :            :         const uno::Reference< XPropertySet > &rxProp )
     219                 :            : {
     220                 :      65832 :     sal_Bool bRes = sal_True;
     221                 :            : 
     222                 :      65832 :     sal_Int32 nLen = rProperties.getLength();
     223                 :      65832 :     const PropertyValue *pVal = rProperties.getConstArray();
     224                 :            :     sal_Int32 i;
     225                 :            : 
     226         [ -  + ]:      65832 :     for ( i = 0;  i < nLen;  ++i)
     227                 :            :     {
     228         [ #  # ]:          0 :         if (UPH_IS_IGNORE_CONTROL_CHARACTERS == pVal[i].Handle)
     229                 :            :         {
     230                 :          0 :             pVal[i].Value >>= bRes;
     231                 :          0 :             break;
     232                 :            :         }
     233                 :            :     }
     234         [ +  - ]:      65832 :     if (i >= nLen)  // no temporary value found in 'rProperties'
     235                 :            :     {
     236         [ +  - ]:      65832 :         uno::Reference< XFastPropertySet > xFast( rxProp, UNO_QUERY );
     237         [ +  - ]:      65832 :         if (xFast.is())
     238 [ +  - ][ +  - ]:      65832 :             xFast->getFastPropertyValue( UPH_IS_IGNORE_CONTROL_CHARACTERS ) >>= bRes;
     239                 :            :     }
     240                 :            : 
     241                 :      65832 :     return bRes;
     242                 :            : }
     243                 :            : 
     244                 :            : 
     245                 :          0 : static sal_Bool lcl_HasHyphInfo( const uno::Reference<XDictionaryEntry> &xEntry )
     246                 :            : {
     247                 :          0 :     sal_Bool bRes = sal_False;
     248         [ #  # ]:          0 :     if (xEntry.is())
     249                 :            :     {
     250                 :            :         // there has to be (at least one) '=' denoting a hyphenation position
     251                 :            :         // and it must not be before any character of the word
     252                 :          0 :         sal_Int32 nIdx = xEntry->getDictionaryWord().indexOf( '=' );
     253 [ #  # ][ #  # ]:          0 :         bRes = nIdx != -1  &&  nIdx != 0;
     254                 :            :     }
     255                 :          0 :     return bRes;
     256                 :            : }
     257                 :            : 
     258                 :            : 
     259                 :      98061 : uno::Reference< XDictionaryEntry > SearchDicList(
     260                 :            :         const uno::Reference< XDictionaryList > &xDicList,
     261                 :            :         const OUString &rWord, sal_Int16 nLanguage,
     262                 :            :         sal_Bool bSearchPosDics, sal_Bool bSearchSpellEntry )
     263                 :            : {
     264 [ +  - ][ +  - ]:      98061 :     MutexGuard  aGuard( GetLinguMutex() );
     265                 :            : 
     266                 :      98061 :     uno::Reference< XDictionaryEntry > xEntry;
     267                 :            : 
     268         [ +  - ]:      98061 :     if (!xDicList.is())
     269                 :            :         return xEntry;
     270                 :            : 
     271                 :            :     const uno::Sequence< uno::Reference< XDictionary > >
     272 [ +  - ][ +  - ]:      98061 :             aDics( xDicList->getDictionaries() );
     273                 :            :     const uno::Reference< XDictionary >
     274                 :      98061 :             *pDic = aDics.getConstArray();
     275 [ +  - ][ +  - ]:      98061 :     sal_Int32 nDics = xDicList->getCount();
     276                 :            : 
     277                 :            :     sal_Int32 i;
     278         [ +  + ]:     585856 :     for (i = 0;  i < nDics;  i++)
     279                 :            :     {
     280         [ +  - ]:     487795 :         uno::Reference< XDictionary > axDic( pDic[i], UNO_QUERY );
     281                 :            : 
     282 [ +  - ][ +  - ]:     487795 :         DictionaryType  eType = axDic->getDictionaryType();
     283 [ +  - ][ +  - ]:     487795 :         sal_Int16           nLang = LocaleToLanguage( axDic->getLocale() );
                 [ +  - ]
     284                 :            : 
     285 [ +  - ][ +  - ]:     487795 :         if ( axDic.is() && axDic->isActive()
         [ +  - ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  - ]
     286                 :            :             && (nLang == nLanguage  ||  nLang == LANGUAGE_NONE) )
     287                 :            :         {
     288                 :            :             DBG_ASSERT( eType != DictionaryType_MIXED,
     289                 :            :                 "lng : unexpected dictionary type" );
     290                 :            : 
     291 [ +  + ][ +  - ]:     292928 :             if (   (!bSearchPosDics  &&  eType == DictionaryType_NEGATIVE)
         [ +  + ][ +  - ]
     292                 :            :                 || ( bSearchPosDics  &&  eType == DictionaryType_POSITIVE))
     293                 :            :             {
     294 [ +  - ][ +  - ]:     196241 :                 if ( (xEntry = axDic->getEntry( rWord )).is() )
         [ +  - ][ +  + ]
     295                 :            :                 {
     296 [ -  + ][ #  # ]:       1255 :                     if (bSearchSpellEntry || lcl_HasHyphInfo( xEntry ))
         [ #  # ][ +  - ]
     297                 :            :                         break;
     298                 :            :                 }
     299         [ +  - ]:     486540 :                 xEntry = 0;
     300                 :            :             }
     301                 :            :         }
     302         [ +  + ]:     487795 :     }
     303                 :            : 
     304 [ +  - ][ +  - ]:      98061 :     return xEntry;
     305                 :            : }
     306                 :            : 
     307                 :            : 
     308                 :          0 : sal_Bool SaveDictionaries( const uno::Reference< XDictionaryList > &xDicList )
     309                 :            : {
     310         [ #  # ]:          0 :     if (!xDicList.is())
     311                 :          0 :         return sal_True;
     312                 :            : 
     313                 :          0 :     sal_Bool bRet = sal_True;
     314                 :            : 
     315 [ #  # ][ #  # ]:          0 :     Sequence< uno::Reference< XDictionary >  > aDics( xDicList->getDictionaries() );
     316                 :          0 :     const uno::Reference< XDictionary >  *pDic = aDics.getConstArray();
     317                 :          0 :     sal_Int32 nCount = aDics.getLength();
     318         [ #  # ]:          0 :     for (sal_Int32 i = 0;  i < nCount;  i++)
     319                 :            :     {
     320                 :            :         try
     321                 :            :         {
     322         [ #  # ]:          0 :             uno::Reference< frame::XStorable >  xStor( pDic[i], UNO_QUERY );
     323         [ #  # ]:          0 :             if (xStor.is())
     324                 :            :             {
     325 [ #  # ][ #  # ]:          0 :                 if (!xStor->isReadonly() && xStor->hasLocation())
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     326 [ #  # ][ #  # ]:          0 :                     xStor->store();
     327         [ #  # ]:          0 :             }
     328                 :            :         }
     329         [ #  # ]:          0 :         catch(uno::Exception &)
     330                 :            :         {
     331                 :          0 :             bRet = sal_False;
     332                 :            :         }
     333                 :            :     }
     334                 :            : 
     335         [ #  # ]:          0 :     return bRet;
     336                 :            : }
     337                 :            : 
     338                 :            : 
     339                 :          0 : sal_uInt8 AddEntryToDic(
     340                 :            :         uno::Reference< XDictionary >  &rxDic,
     341                 :            :         const OUString &rWord, sal_Bool bIsNeg,
     342                 :            :         const OUString &rRplcTxt, sal_Int16 /* nRplcLang */,
     343                 :            :         sal_Bool bStripDot )
     344                 :            : {
     345         [ #  # ]:          0 :     if (!rxDic.is())
     346                 :          0 :         return DIC_ERR_NOT_EXISTS;
     347                 :            : 
     348                 :          0 :     OUString aTmp( rWord );
     349         [ #  # ]:          0 :     if (bStripDot)
     350                 :            :     {
     351                 :          0 :         sal_Int32 nLen = rWord.getLength();
     352 [ #  # ][ #  # ]:          0 :         if (nLen > 0  &&  '.' == rWord[ nLen - 1])
                 [ #  # ]
     353                 :            :         {
     354                 :            :             // remove trailing '.'
     355                 :            :             // (this is the official way to do this :-( )
     356                 :          0 :             aTmp = aTmp.copy( 0, nLen - 1 );
     357                 :            :         }
     358                 :            :     }
     359 [ #  # ][ #  # ]:          0 :     sal_Bool bAddOk = rxDic->add( aTmp, bIsNeg, rRplcTxt );
     360                 :            : 
     361                 :          0 :     sal_uInt8 nRes = DIC_ERR_NONE;
     362         [ #  # ]:          0 :     if (!bAddOk)
     363                 :            :     {
     364 [ #  # ][ #  # ]:          0 :         if (rxDic->isFull())
                 [ #  # ]
     365                 :          0 :             nRes = DIC_ERR_FULL;
     366                 :            :         else
     367                 :            :         {
     368         [ #  # ]:          0 :             uno::Reference< frame::XStorable >  xStor( rxDic, UNO_QUERY );
     369 [ #  # ][ #  # ]:          0 :             if (xStor.is() && xStor->isReadonly())
         [ #  # ][ #  # ]
                 [ #  # ]
     370                 :          0 :                 nRes = DIC_ERR_READONLY;
     371                 :            :             else
     372                 :          0 :                 nRes = DIC_ERR_UNKNOWN;
     373                 :            :         }
     374                 :            :     }
     375                 :            : 
     376                 :          0 :     return nRes;
     377                 :            : }
     378                 :            : 
     379                 :            : 
     380                 :            : 
     381                 :     733873 : LanguageType LocaleToLanguage( const Locale& rLocale )
     382                 :            : {
     383                 :            :     //  empty Locale -> LANGUAGE_NONE
     384         [ +  + ]:     733873 :     if ( rLocale.Language.isEmpty() )
     385                 :     241456 :         return LANGUAGE_NONE;
     386                 :            : 
     387                 :     733873 :     return MsLangId::convertLocaleToLanguage( rLocale );
     388                 :            : }
     389                 :            : 
     390                 :            : 
     391                 :     487795 : Locale& LanguageToLocale( Locale& rLocale, LanguageType eLang )
     392                 :            : {
     393         [ +  + ]:     487795 :     if ( eLang != LANGUAGE_NONE /* &&  eLang != LANGUAGE_SYSTEM */)
     394                 :     292928 :         MsLangId::convertLanguageToLocale( eLang, rLocale );
     395                 :            : 
     396                 :     487795 :     return rLocale;
     397                 :            : }
     398                 :            : 
     399                 :     189810 : Locale CreateLocale( LanguageType eLang )
     400                 :            : {
     401                 :     189810 :     Locale aLocale;
     402         [ +  + ]:     189810 :     if ( eLang != LANGUAGE_NONE /* &&  eLang != LANGUAGE_SYSTEM */)
     403         [ +  - ]:     189759 :         return MsLangId::convertLanguageToLocale( eLang );
     404                 :            : 
     405                 :     189810 :     return aLocale;
     406                 :            : }
     407                 :            : 
     408                 :            : uno::Sequence< sal_Int16 >
     409                 :        192 :     LocaleSeqToLangSeq( uno::Sequence< Locale > &rLocaleSeq )
     410                 :            : {
     411                 :        192 :     const Locale *pLocale = rLocaleSeq.getConstArray();
     412                 :        192 :     sal_Int32 nCount = rLocaleSeq.getLength();
     413                 :            : 
     414                 :        192 :     uno::Sequence< sal_Int16 >   aLangs( nCount );
     415         [ +  - ]:        192 :     sal_Int16 *pLang = aLangs.getArray();
     416         [ +  + ]:       7392 :     for (sal_Int32 i = 0;  i < nCount;  ++i)
     417                 :            :     {
     418         [ +  - ]:       7200 :         pLang[i] = LocaleToLanguage( pLocale[i] );
     419                 :            :     }
     420                 :            : 
     421                 :        192 :     return aLangs;
     422                 :            : }
     423                 :            : 
     424                 :            : 
     425                 :          0 : sal_Bool    IsReadOnly( const String &rURL, sal_Bool *pbExist )
     426                 :            : {
     427                 :          0 :     sal_Bool bRes = sal_False;
     428                 :          0 :     sal_Bool bExists = sal_False;
     429                 :            : 
     430         [ #  # ]:          0 :     if (rURL.Len() > 0)
     431                 :            :     {
     432                 :            :         try
     433                 :            :         {
     434                 :          0 :             uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv;
     435 [ #  # ][ #  # ]:          0 :             ::ucbhelper::Content aContent( rURL, xCmdEnv );
     436                 :            : 
     437         [ #  # ]:          0 :             bExists = aContent.isDocument();
     438         [ #  # ]:          0 :             if (bExists)
     439                 :            :             {
     440 [ #  # ][ #  # ]:          0 :                 Any aAny( aContent.getPropertyValue( A2OU( "IsReadOnly" ) ) );
     441                 :          0 :                 aAny >>= bRes;
     442 [ #  # ][ #  # ]:          0 :             }
     443                 :            :         }
     444         [ #  # ]:          0 :         catch (Exception &)
     445                 :            :         {
     446                 :          0 :             bRes = sal_True;
     447                 :            :         }
     448                 :            :     }
     449                 :            : 
     450         [ #  # ]:          0 :     if (pbExist)
     451                 :          0 :         *pbExist = bExists;
     452                 :          0 :     return bRes;
     453                 :            : }
     454                 :            : 
     455                 :            : 
     456                 :            : 
     457                 :          0 : static sal_Bool GetAltSpelling( sal_Int16 &rnChgPos, sal_Int16 &rnChgLen, OUString &rRplc,
     458                 :            :         uno::Reference< XHyphenatedWord > &rxHyphWord )
     459                 :            : {
     460                 :          0 :     sal_Bool bRes = rxHyphWord->isAlternativeSpelling();
     461         [ #  # ]:          0 :     if (bRes)
     462                 :            :     {
     463 [ #  # ][ #  # ]:          0 :         OUString aWord( rxHyphWord->getWord() ),
     464 [ #  # ][ #  # ]:          0 :                  aHyphenatedWord( rxHyphWord->getHyphenatedWord() );
     465 [ #  # ][ #  # ]:          0 :         sal_Int16   nHyphenationPos     = rxHyphWord->getHyphenationPos();
     466                 :            :         /*sal_Int16   nHyphenPos          = rxHyphWord->getHyphenPos()*/;
     467                 :          0 :         const sal_Unicode *pWord    = aWord.getStr(),
     468                 :          0 :                           *pAltWord = aHyphenatedWord.getStr();
     469                 :            : 
     470                 :            :         // at least char changes directly left or right to the hyphen
     471                 :            :         // should(!) be handled properly...
     472                 :            :         //! nHyphenationPos and nHyphenPos differ at most by 1 (see above)
     473                 :            :         //! Beware: eg "Schiffahrt" in German (pre spelling reform)
     474                 :            :         //! proves to be a bit nasty (nChgPosLeft and nChgPosRight overlap
     475                 :            :         //! to an extend.)
     476                 :            : 
     477                 :            :         // find first different char from left
     478                 :          0 :         sal_Int32   nPosL    = 0,
     479                 :          0 :                     nAltPosL = 0;
     480         [ #  # ]:          0 :         for (sal_Int16 i = 0 ;  pWord[ nPosL ] == pAltWord[ nAltPosL ];  nPosL++, nAltPosL++, i++)
     481                 :            :         {
     482                 :            :             // restrict changes area beginning to the right to
     483                 :            :             // the char immediately following the hyphen.
     484                 :            :             //! serves to insert the additional "f" in "Schiffahrt" at
     485                 :            :             //! position 5 rather than position 6.
     486         [ #  # ]:          0 :             if (i >= nHyphenationPos + 1)
     487                 :          0 :                 break;
     488                 :            :         }
     489                 :            : 
     490                 :            :         // find first different char from right
     491                 :          0 :         sal_Int32   nPosR    = aWord.getLength() - 1,
     492                 :          0 :                     nAltPosR = aHyphenatedWord.getLength() - 1;
     493 [ #  # ][ #  # ]:          0 :         for ( ;  nPosR >= nPosL  &&  nAltPosR >= nAltPosL
         [ #  # ][ #  # ]
     494                 :          0 :                     &&  pWord[ nPosR ] == pAltWord[ nAltPosR ];
     495                 :            :                 nPosR--, nAltPosR--)
     496                 :            :             ;
     497                 :            : 
     498                 :          0 :         rnChgPos = sal::static_int_cast< sal_Int16 >(nPosL);
     499                 :          0 :         rnChgLen = sal::static_int_cast< sal_Int16 >(nPosR - nPosL + 1);
     500                 :            :         DBG_ASSERT( rnChgLen >= 0, "nChgLen < 0");
     501                 :            : 
     502                 :          0 :         sal_Int32 nTxtStart = nPosL;
     503                 :          0 :         sal_Int32 nTxtLen   = nAltPosL - nPosL + 1;
     504                 :          0 :         rRplc = aHyphenatedWord.copy( nTxtStart, nTxtLen );
     505                 :            :     }
     506                 :          0 :     return bRes;
     507                 :            : }
     508                 :            : 
     509                 :            : 
     510                 :          0 : static sal_Int16 GetOrigWordPos( const OUString &rOrigWord, sal_Int16 nPos )
     511                 :            : {
     512                 :          0 :     sal_Int32 nLen = rOrigWord.getLength();
     513                 :          0 :     sal_Int32 i = -1;
     514 [ #  # ][ #  # ]:          0 :     while (nPos >= 0  &&  i++ < nLen)
                 [ #  # ]
     515                 :            :     {
     516                 :          0 :         sal_Unicode cChar = rOrigWord[i];
     517 [ #  # ][ #  # ]:          0 :         sal_Bool bSkip = IsHyphen( cChar ) || IsControlChar( cChar );
     518         [ #  # ]:          0 :         if (!bSkip)
     519                 :          0 :             --nPos;
     520                 :            :     }
     521 [ #  # ][ #  # ]:          0 :     return sal::static_int_cast< sal_Int16 >((0 <= i  &&  i < nLen) ? i : -1);
     522                 :            : }
     523                 :            : 
     524                 :            : 
     525                 :      67206 : sal_Int32 GetPosInWordToCheck( const OUString &rTxt, sal_Int32 nPos )
     526                 :            : {
     527                 :      67206 :     sal_Int32 nRes = -1;
     528                 :      67206 :     sal_Int32 nLen = rTxt.getLength();
     529 [ +  - ][ +  - ]:      67206 :     if (0 <= nPos  &&  nPos < nLen)
     530                 :            :     {
     531                 :      67206 :         nRes = 0;
     532         [ +  + ]:     140096 :         for (sal_Int32 i = 0;  i < nPos;  ++i)
     533                 :            :         {
     534                 :      72890 :             sal_Unicode cChar = rTxt[i];
     535 [ -  + ][ +  - ]:      72890 :             sal_Bool bSkip = IsHyphen( cChar ) || IsControlChar( cChar );
     536         [ +  - ]:      72890 :             if (!bSkip)
     537                 :      72890 :                 ++nRes;
     538                 :            :         }
     539                 :            :     }
     540                 :      67206 :     return nRes;
     541                 :            : }
     542                 :            : 
     543                 :            : 
     544                 :          0 : uno::Reference< XHyphenatedWord > RebuildHyphensAndControlChars(
     545                 :            :         const OUString &rOrigWord,
     546                 :            :         uno::Reference< XHyphenatedWord > &rxHyphWord )
     547                 :            : {
     548                 :          0 :     uno::Reference< XHyphenatedWord > xRes;
     549 [ #  # ][ #  # ]:          0 :     if (!rOrigWord.isEmpty() && rxHyphWord.is())
                 [ #  # ]
     550                 :            :     {
     551                 :          0 :         sal_Int16    nChgPos = 0,
     552                 :          0 :                  nChgLen = 0;
     553                 :          0 :         OUString aRplc;
     554         [ #  # ]:          0 :         sal_Bool bAltSpelling = GetAltSpelling( nChgPos, nChgLen, aRplc, rxHyphWord );
     555                 :            : #if OSL_DEBUG_LEVEL > 1
     556                 :            :         OUString aWord( rxHyphWord->getWord() );
     557                 :            : #endif
     558                 :            : 
     559                 :          0 :         OUString aOrigHyphenatedWord;
     560                 :          0 :         sal_Int16 nOrigHyphenPos        = -1;
     561                 :          0 :         sal_Int16 nOrigHyphenationPos   = -1;
     562         [ #  # ]:          0 :         if (!bAltSpelling)
     563                 :            :         {
     564                 :          0 :             aOrigHyphenatedWord = rOrigWord;
     565 [ #  # ][ #  # ]:          0 :             nOrigHyphenPos      = GetOrigWordPos( rOrigWord, rxHyphWord->getHyphenPos() );
                 [ #  # ]
     566 [ #  # ][ #  # ]:          0 :             nOrigHyphenationPos = GetOrigWordPos( rOrigWord, rxHyphWord->getHyphenationPos() );
                 [ #  # ]
     567                 :            :         }
     568                 :            :         else
     569                 :            :         {
     570                 :            :             //! should at least work with the German words
     571                 :            :             //! B�-c-k-er and Sc-hif-fah-rt
     572                 :            : 
     573                 :          0 :             OUString aLeft, aRight;
     574         [ #  # ]:          0 :             sal_Int16 nPos = GetOrigWordPos( rOrigWord, nChgPos );
     575                 :            : 
     576                 :            :             // get words like Sc-hif-fah-rt to work correct
     577 [ #  # ][ #  # ]:          0 :             sal_Int16 nHyphenationPos = rxHyphWord->getHyphenationPos();
     578         [ #  # ]:          0 :             if (nChgPos > nHyphenationPos)
     579                 :          0 :                 --nPos;
     580                 :            : 
     581                 :          0 :             aLeft = rOrigWord.copy( 0, nPos );
     582                 :          0 :             aRight = rOrigWord.copy( nPos + nChgLen );
     583                 :            : 
     584                 :          0 :             aOrigHyphenatedWord =  aLeft;
     585                 :          0 :             aOrigHyphenatedWord += aRplc;
     586                 :          0 :             aOrigHyphenatedWord += aRight;
     587                 :            : 
     588                 :          0 :             nOrigHyphenPos      = sal::static_int_cast< sal_Int16 >(aLeft.getLength() +
     589 [ #  # ][ #  # ]:          0 :                                   rxHyphWord->getHyphenPos() - nChgPos);
     590         [ #  # ]:          0 :             nOrigHyphenationPos = GetOrigWordPos( rOrigWord, nHyphenationPos );
     591                 :            :         }
     592                 :            : 
     593 [ #  # ][ #  # ]:          0 :         if (nOrigHyphenPos == -1  ||  nOrigHyphenationPos == -1)
     594                 :            :         {
     595                 :            :             DBG_ASSERT( 0, "failed to get nOrigHyphenPos or nOrigHyphenationPos" );
     596                 :            :         }
     597                 :            :         else
     598                 :            :         {
     599 [ #  # ][ #  # ]:          0 :             sal_Int16 nLang = LocaleToLanguage( rxHyphWord->getLocale() );
                 [ #  # ]
     600                 :            :             xRes = new HyphenatedWord(
     601                 :            :                         rOrigWord, nLang, nOrigHyphenationPos,
     602 [ #  # ][ #  # ]:          0 :                         aOrigHyphenatedWord, nOrigHyphenPos );
                 [ #  # ]
     603                 :          0 :         }
     604                 :            : 
     605                 :            :     }
     606                 :          0 :     return xRes;
     607                 :            : }
     608                 :            : 
     609                 :            : 
     610                 :            : 
     611                 :            : 
     612                 :      13033 : static CharClass & lcl_GetCharClass()
     613                 :            : {
     614 [ +  + ][ +  - ]:      13033 :     static CharClass aCC( CreateLocale( LANGUAGE_ENGLISH_US ) );
         [ +  - ][ +  - ]
                 [ #  # ]
     615                 :      13033 :     return aCC;
     616                 :            : }
     617                 :            : 
     618                 :            : 
     619                 :      13033 : osl::Mutex & lcl_GetCharClassMutex()
     620                 :            : {
     621 [ +  + ][ +  - ]:      13033 :     static osl::Mutex   aMutex;
         [ +  - ][ #  # ]
     622                 :      13033 :     return aMutex;
     623                 :            : }
     624                 :            : 
     625                 :            : 
     626                 :      12613 : sal_Bool IsUpper( const String &rText, xub_StrLen nPos, xub_StrLen nLen, sal_Int16 nLanguage )
     627                 :            : {
     628 [ +  - ][ +  - ]:      12613 :     MutexGuard  aGuard( lcl_GetCharClassMutex() );
     629                 :            : 
     630         [ +  - ]:      12613 :     CharClass &rCC = lcl_GetCharClass();
     631 [ +  - ][ +  - ]:      12613 :     rCC.setLocale( CreateLocale( nLanguage ) );
     632         [ +  - ]:      12613 :     sal_Int32 nFlags = rCC.getStringType( rText, nPos, nLen );
     633                 :            :     return      (nFlags & KCharacterType::UPPER)
     634 [ +  + ][ +  + ]:      12613 :             && !(nFlags & KCharacterType::LOWER);
                 [ +  - ]
     635                 :            : }
     636                 :            : 
     637                 :            : 
     638                 :        420 : String ToLower( const String &rText, sal_Int16 nLanguage )
     639                 :            : {
     640 [ +  - ][ +  - ]:        420 :     MutexGuard  aGuard( lcl_GetCharClassMutex() );
     641                 :            : 
     642         [ +  - ]:        420 :     CharClass &rCC = lcl_GetCharClass();
     643 [ +  - ][ +  - ]:        420 :     rCC.setLocale( CreateLocale( nLanguage ) );
     644 [ +  - ][ +  - ]:        420 :     return rCC.lowercase( rText );
         [ +  - ][ +  - ]
     645                 :            : }
     646                 :            : 
     647                 :            : 
     648                 :            : // sorted(!) array of unicode ranges for code points that are exclusively(!) used as numbers
     649                 :            : // and thus may NOT not be part of names or words like the Chinese/Japanese number characters
     650                 :            : static const sal_uInt32 the_aDigitZeroes [] =
     651                 :            : {
     652                 :            :     0x00000030, //0039    ; Decimal # Nd  [10] DIGIT ZERO..DIGIT NINE
     653                 :            :     0x00000660, //0669    ; Decimal # Nd  [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
     654                 :            :     0x000006F0, //06F9    ; Decimal # Nd  [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
     655                 :            :     0x000007C0, //07C9    ; Decimal # Nd  [10] NKO DIGIT ZERO..NKO DIGIT NINE
     656                 :            :     0x00000966, //096F    ; Decimal # Nd  [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
     657                 :            :     0x000009E6, //09EF    ; Decimal # Nd  [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
     658                 :            :     0x00000A66, //0A6F    ; Decimal # Nd  [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
     659                 :            :     0x00000AE6, //0AEF    ; Decimal # Nd  [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
     660                 :            :     0x00000B66, //0B6F    ; Decimal # Nd  [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
     661                 :            :     0x00000BE6, //0BEF    ; Decimal # Nd  [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
     662                 :            :     0x00000C66, //0C6F    ; Decimal # Nd  [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
     663                 :            :     0x00000CE6, //0CEF    ; Decimal # Nd  [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
     664                 :            :     0x00000D66, //0D6F    ; Decimal # Nd  [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
     665                 :            :     0x00000E50, //0E59    ; Decimal # Nd  [10] THAI DIGIT ZERO..THAI DIGIT NINE
     666                 :            :     0x00000ED0, //0ED9    ; Decimal # Nd  [10] LAO DIGIT ZERO..LAO DIGIT NINE
     667                 :            :     0x00000F20, //0F29    ; Decimal # Nd  [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
     668                 :            :     0x00001040, //1049    ; Decimal # Nd  [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
     669                 :            :     0x00001090, //1099    ; Decimal # Nd  [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
     670                 :            :     0x000017E0, //17E9    ; Decimal # Nd  [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
     671                 :            :     0x00001810, //1819    ; Decimal # Nd  [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
     672                 :            :     0x00001946, //194F    ; Decimal # Nd  [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
     673                 :            :     0x000019D0, //19D9    ; Decimal # Nd  [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
     674                 :            :     0x00001B50, //1B59    ; Decimal # Nd  [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
     675                 :            :     0x00001BB0, //1BB9    ; Decimal # Nd  [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
     676                 :            :     0x00001C40, //1C49    ; Decimal # Nd  [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
     677                 :            :     0x00001C50, //1C59    ; Decimal # Nd  [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
     678                 :            :     0x0000A620, //A629    ; Decimal # Nd  [10] VAI DIGIT ZERO..VAI DIGIT NINE
     679                 :            :     0x0000A8D0, //A8D9    ; Decimal # Nd  [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
     680                 :            :     0x0000A900, //A909    ; Decimal # Nd  [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
     681                 :            :     0x0000AA50, //AA59    ; Decimal # Nd  [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
     682                 :            :     0x0000FF10, //FF19    ; Decimal # Nd  [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
     683                 :            :     0x000104A0, //104A9   ; Decimal # Nd  [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
     684                 :            :     0x0001D7CE  //1D7FF   ; Decimal # Nd  [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
     685                 :            : };
     686                 :            : 
     687                 :      12449 : sal_Bool HasDigits( const OUString &rText )
     688                 :            : {
     689                 :            :     static const int nNumDigitZeroes = sizeof(the_aDigitZeroes) / sizeof(the_aDigitZeroes[0]);
     690                 :      12449 :     const sal_Int32 nLen = rText.getLength();
     691                 :            : 
     692                 :      12449 :     sal_Int32 i = 0;
     693         [ +  + ]:      72453 :     while (i < nLen) // for all characters ...
     694                 :            :     {
     695         [ +  - ]:      68357 :         const sal_uInt32 nCodePoint = rText.iterateCodePoints( &i );    // handle unicode surrogates correctly...
     696         [ +  - ]:     128243 :         for (int j = 0; j < nNumDigitZeroes; ++j)   // ... check in all 0..9 ranges
     697                 :            :         {
     698                 :     128243 :             sal_uInt32 nDigitZero = the_aDigitZeroes[ j ];
     699         [ +  + ]:     128243 :             if (nDigitZero > nCodePoint)
     700                 :      60004 :                 break;
     701         [ +  + ]:      68239 :             if (/*nDigitZero <= nCodePoint &&*/ nCodePoint <= nDigitZero + 9)
     702                 :       8353 :                 return sal_True;
     703                 :            :         }
     704                 :            :     }
     705                 :      12449 :     return sal_False;
     706                 :            : }
     707                 :            : 
     708                 :            : 
     709                 :          0 : sal_Bool IsNumeric( const String &rText )
     710                 :            : {
     711                 :          0 :     sal_Bool bRes = sal_False;
     712                 :          0 :     xub_StrLen nLen = rText.Len();
     713         [ #  # ]:          0 :     if (nLen)
     714                 :            :     {
     715                 :          0 :         bRes = sal_True;
     716                 :          0 :         xub_StrLen i = 0;
     717         [ #  # ]:          0 :         while (i < nLen)
     718                 :            :         {
     719                 :          0 :             sal_Unicode cChar = rText.GetChar( i++ );
     720 [ #  # ][ #  # ]:          0 :             if ( !((sal_Unicode)'0' <= cChar  &&  cChar <= (sal_Unicode)'9') )
     721                 :            :             {
     722                 :          0 :                 bRes = sal_False;
     723                 :          0 :                 break;
     724                 :            :             }
     725                 :            :         }
     726                 :            :     }
     727                 :          0 :     return bRes;
     728                 :            : }
     729                 :            : 
     730                 :            : 
     731                 :            : 
     732                 :      64919 : uno::Reference< XInterface > GetOneInstanceService( const char *pServiceName )
     733                 :            : {
     734                 :      64919 :     uno::Reference< XInterface > xRef;
     735                 :            : 
     736         [ +  - ]:      64919 :     if (pServiceName)
     737                 :            :     {
     738                 :            :         uno::Reference< XMultiServiceFactory > xMgr(
     739         [ +  - ]:      64919 :             comphelper::getProcessServiceFactory() );
     740         [ +  - ]:      64919 :         if (xMgr.is())
     741                 :            :         {
     742                 :            :             try
     743                 :            :             {
     744 [ +  - ][ +  - ]:      64919 :                 xRef = xMgr->createInstance( ::rtl::OUString::createFromAscii( pServiceName ) );
         [ +  - ][ #  # ]
     745                 :            :             }
     746         [ #  # ]:          0 :             catch (uno::Exception &)
     747                 :            :             {
     748                 :            :                 DBG_ASSERT( 0, "createInstance failed" );
     749                 :            :             }
     750                 :      64919 :         }
     751                 :            :     }
     752                 :            : 
     753                 :      64919 :     return xRef;
     754                 :            : }
     755                 :            : 
     756                 :        330 : uno::Reference< XPropertySet > GetLinguProperties()
     757                 :            : {
     758                 :            :     return uno::Reference< XPropertySet > (
     759         [ +  - ]:        330 :         GetOneInstanceService( SN_LINGU_PROPERTIES ), UNO_QUERY );
     760                 :            : }
     761                 :            : 
     762                 :         49 : uno::Reference< XSearchableDictionaryList > GetSearchableDictionaryList()
     763                 :            : {
     764                 :            :     return uno::Reference< XSearchableDictionaryList > (
     765         [ +  - ]:         49 :         GetOneInstanceService( SN_DICTIONARY_LIST ), UNO_QUERY );
     766                 :            : }
     767                 :            : 
     768                 :      64540 : uno::Reference< XDictionaryList > GetDictionaryList()
     769                 :            : {
     770                 :            :     return uno::Reference< XDictionaryList > (
     771         [ +  - ]:      64540 :         GetOneInstanceService( SN_DICTIONARY_LIST ), UNO_QUERY );
     772                 :            : }
     773                 :            : 
     774                 :      32229 : uno::Reference< XDictionary > GetIgnoreAllList()
     775                 :            : {
     776                 :      32229 :     uno::Reference< XDictionary > xRes;
     777         [ +  - ]:      32229 :     uno::Reference< XDictionaryList > xDL( GetDictionaryList() );
     778         [ +  - ]:      32229 :     if (xDL.is())
     779 [ +  - ][ +  - ]:      32229 :         xRes = xDL->getDictionaryByName( A2OU("IgnoreAllList") );
         [ +  - ][ +  - ]
     780                 :      32229 :     return xRes;
     781                 :            : }
     782                 :            : 
     783                 :            : 
     784                 :         44 : AppExitListener::AppExitListener()
     785                 :            : {
     786                 :            :     // add object to Desktop EventListeners in order to properly call
     787                 :            :     // the AtExit function at appliction exit.
     788                 :            :     uno::Reference< XMultiServiceFactory > xMgr(
     789         [ +  - ]:         44 :         comphelper::getProcessServiceFactory() );
     790                 :            : 
     791         [ +  - ]:         44 :     if (xMgr.is())
     792                 :            :     {
     793                 :            :         try
     794                 :            :         {
     795                 :            :             xDesktop = uno::Reference< frame::XDesktop >(
     796 [ +  - ][ +  - ]:         44 :                     xMgr->createInstance( A2OU( SN_DESKTOP ) ), UNO_QUERY );
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
     797                 :            :         }
     798         [ #  # ]:          0 :         catch (uno::Exception &)
     799                 :            :         {
     800                 :            :             DBG_ASSERT( 0, "createInstance failed" );
     801                 :            :         }
     802                 :         44 :     }
     803                 :         44 : }
     804                 :            : 
     805                 :         42 : AppExitListener::~AppExitListener()
     806                 :            : {
     807         [ -  + ]:         42 : }
     808                 :            : 
     809                 :            : 
     810                 :         44 : void AppExitListener::Activate()
     811                 :            : {
     812         [ +  - ]:         44 :     if (xDesktop.is())
     813         [ +  - ]:         44 :         xDesktop->addTerminateListener( this );
     814                 :         44 : }
     815                 :            : 
     816                 :            : 
     817                 :         42 : void AppExitListener::Deactivate()
     818                 :            : {
     819         [ +  + ]:         42 :     if (xDesktop.is())
     820         [ +  - ]:         20 :         xDesktop->removeTerminateListener( this );
     821                 :         42 : }
     822                 :            : 
     823                 :            : 
     824                 :            : void SAL_CALL
     825                 :         24 :     AppExitListener::disposing( const EventObject& rEvtSource )
     826                 :            :         throw(RuntimeException)
     827                 :            : {
     828 [ +  - ][ +  - ]:         24 :     MutexGuard  aGuard( GetLinguMutex() );
     829                 :            : 
     830 [ +  - ][ +  - ]:         24 :     if (xDesktop.is()  &&  rEvtSource.Source == xDesktop)
         [ +  - ][ +  - ]
     831                 :            :     {
     832         [ +  - ]:         24 :         xDesktop = NULL;    //! release reference to desktop
     833         [ +  - ]:         24 :     }
     834                 :         24 : }
     835                 :            : 
     836                 :            : 
     837                 :            : void SAL_CALL
     838                 :         44 :     AppExitListener::queryTermination( const EventObject& /*rEvtSource*/ )
     839                 :            :         throw(frame::TerminationVetoException, RuntimeException)
     840                 :            : {
     841                 :         44 : }
     842                 :            : 
     843                 :            : 
     844                 :            : void SAL_CALL
     845                 :         44 :     AppExitListener::notifyTermination( const EventObject& rEvtSource )
     846                 :            :         throw(RuntimeException)
     847                 :            : {
     848 [ +  - ][ +  - ]:         44 :     MutexGuard  aGuard( GetLinguMutex() );
     849                 :            : 
     850 [ +  - ][ +  - ]:         44 :     if (xDesktop.is()  &&  rEvtSource.Source == xDesktop)
         [ +  - ][ +  - ]
     851                 :            :     {
     852         [ +  - ]:         44 :         AtExit();
     853         [ +  - ]:         44 :     }
     854                 :         44 : }
     855                 :            : 
     856                 :            : 
     857                 :            : }   // namespace linguistic
     858                 :            : 
     859                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10