LCOV - code coverage report
Current view: top level - lingucomponent/source/thesaurus/libnth - nthesimp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 121 375 32.3 %
Date: 2012-08-25 Functions: 9 23 39.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 138 734 18.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                 :            : 
      30                 :            : #include <com/sun/star/uno/Reference.h>
      31                 :            : #include <cppuhelper/factory.hxx>   // helper for factories
      32                 :            : #include <com/sun/star/registry/XRegistryKey.hpp>
      33                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      34                 :            : #include <i18npool/mslangid.hxx>
      35                 :            : #include <tools/debug.hxx>
      36                 :            : #include <comphelper/processfactory.hxx>
      37                 :            : #include <osl/mutex.hxx>
      38                 :            : #include <unotools/pathoptions.hxx>
      39                 :            : #include <unotools/lingucfg.hxx>
      40                 :            : 
      41                 :            : #include <rtl/string.hxx>
      42                 :            : #include <rtl/ustrbuf.hxx>
      43                 :            : #include <rtl/textenc.h>
      44                 :            : 
      45                 :            : #include "nthesimp.hxx"
      46                 :            : #include <linguistic/misc.hxx>
      47                 :            : #include <linguistic/lngprops.hxx>
      48                 :            : #include "nthesdta.hxx"
      49                 :            : #include <dictmgr.hxx>
      50                 :            : 
      51                 :            : #include <list>
      52                 :            : #include <set>
      53                 :            : #include <string.h>
      54                 :            : 
      55                 :            : // values asigned to capitalization types
      56                 :            : #define CAPTYPE_UNKNOWN 0
      57                 :            : #define CAPTYPE_NOCAP   1
      58                 :            : #define CAPTYPE_INITCAP 2
      59                 :            : #define CAPTYPE_ALLCAP  3
      60                 :            : #define CAPTYPE_MIXED   4
      61                 :            : 
      62                 :            : // XML-header to query SPELLML support
      63                 :            : #define SPELLML_SUPPORT "<?xml?>"
      64                 :            : 
      65                 :            : using namespace osl;
      66                 :            : using namespace com::sun::star;
      67                 :            : using namespace com::sun::star::beans;
      68                 :            : using namespace com::sun::star::lang;
      69                 :            : using namespace com::sun::star::uno;
      70                 :            : using namespace com::sun::star::linguistic2;
      71                 :            : using namespace linguistic;
      72                 :            : 
      73                 :            : using ::rtl::OUString;
      74                 :            : using ::rtl::OString;
      75                 :            : using ::rtl::OUStringToOString;
      76                 :            : 
      77                 :            : ///////////////////////////////////////////////////////////////////////////
      78                 :            : 
      79                 :          0 : static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
      80                 :            : {
      81                 :          0 :     uno::Reference< XLinguServiceManager > xRes;
      82                 :            :     uno::Reference< XMultiServiceFactory > xMgr(
      83         [ #  # ]:          0 :         comphelper::getProcessServiceFactory() );
      84         [ #  # ]:          0 :     if (xMgr.is())
      85                 :            :     {
      86         [ #  # ]:          0 :         xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance(
      87                 :            :                 OUString( RTL_CONSTASCII_USTRINGPARAM(
      88 [ #  # ][ #  # ]:          0 :                     "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ;
         [ #  # ][ #  # ]
      89                 :            :     }
      90                 :          0 :     return xRes;
      91                 :            : }
      92                 :            : 
      93                 :         46 : Thesaurus::Thesaurus() :
      94 [ +  - ][ +  - ]:         46 :     aEvtListeners   ( GetLinguMutex() )
         [ +  - ][ +  - ]
      95                 :            : {
      96                 :         46 :     bDisposing = sal_False;
      97                 :         46 :     pPropHelper = NULL;
      98                 :         46 :     aThes = NULL;
      99                 :         46 :     aCharSetInfo = NULL;
     100                 :         46 :     aTEncs = NULL;
     101                 :         46 :     aTLocs = NULL;
     102                 :         46 :     aTNames = NULL;
     103                 :         46 :     numthes = 0;
     104                 :         46 : }
     105                 :            : 
     106                 :            : 
     107 [ +  - ][ +  - ]:         46 : Thesaurus::~Thesaurus()
                 [ +  - ]
     108                 :            : {
     109         [ +  - ]:         46 :     if (aThes)
     110                 :            :     {
     111         [ +  + ]:       2116 :         for (int i = 0; i < numthes; i++)
     112                 :            :         {
     113 [ -  + ][ #  # ]:       2070 :             if (aThes[i]) delete aThes[i];
                 [ #  # ]
     114                 :       2070 :             aThes[i] = NULL;
     115                 :            :         }
     116         [ +  - ]:         46 :         delete[] aThes;
     117                 :            :     }
     118                 :         46 :     aThes = NULL;
     119         [ +  - ]:         46 :     if (aCharSetInfo)
     120                 :            :     {
     121         [ +  + ]:       2116 :         for (int i = 0; i < numthes; i++)
     122                 :            :         {
     123 [ +  - ][ +  - ]:       2070 :             if (aCharSetInfo[i]) delete aCharSetInfo[i];
                 [ +  - ]
     124                 :       2070 :             aCharSetInfo[i] = NULL;
     125                 :            :         }
     126         [ +  - ]:         46 :         delete[] aCharSetInfo;
     127                 :            :     }
     128                 :         46 :     aCharSetInfo = NULL;
     129                 :         46 :     numthes = 0;
     130 [ +  - ][ +  - ]:         46 :     if (aTEncs) delete[] aTEncs;
     131                 :         46 :     aTEncs = NULL;
     132 [ +  - ][ +  - ]:       2116 :     if (aTLocs) delete[] aTLocs;
                 [ +  + ]
     133                 :         46 :     aTLocs = NULL;
     134 [ +  - ][ +  - ]:       2116 :     if (aTNames) delete[] aTNames;
                 [ +  + ]
     135                 :         46 :     aTNames = NULL;
     136                 :            : 
     137         [ -  + ]:         46 :     if (pPropHelper)
     138                 :            :     {
     139         [ #  # ]:          0 :         pPropHelper->RemoveAsPropListener();
     140 [ #  # ][ #  # ]:          0 :         delete pPropHelper;
     141                 :            :     }
     142         [ -  + ]:         92 : }
     143                 :            : 
     144                 :            : 
     145                 :          0 : PropertyHelper_Thesaurus& Thesaurus::GetPropHelper_Impl()
     146                 :            : {
     147         [ #  # ]:          0 :     if (!pPropHelper)
     148                 :            :     {
     149 [ #  # ][ #  # ]:          0 :         Reference< XPropertySet >   xPropSet( GetLinguProperties(), UNO_QUERY );
     150                 :            : 
     151 [ #  # ][ #  # ]:          0 :         pPropHelper = new PropertyHelper_Thesaurus( (XThesaurus *) this, xPropSet );
                 [ #  # ]
     152         [ #  # ]:          0 :         pPropHelper->AddAsPropListener();   //! after a reference is established
     153                 :            :     }
     154                 :          0 :     return *pPropHelper;
     155                 :            : }
     156                 :            : 
     157                 :            : 
     158                 :         96 : Sequence< Locale > SAL_CALL Thesaurus::getLocales()
     159                 :            :         throw(RuntimeException)
     160                 :            : {
     161 [ +  - ][ +  - ]:         96 :     MutexGuard  aGuard( GetLinguMutex() );
     162                 :            : 
     163                 :            :     // this routine should return the locales supported by the installed
     164                 :            :     // dictionaries.
     165                 :            : 
     166         [ +  + ]:         96 :     if (!numthes)
     167                 :            :     {
     168         [ +  - ]:         46 :         SvtLinguConfig aLinguCfg;
     169                 :            : 
     170                 :            :         // get list of dictionaries-to-use
     171         [ +  - ]:         46 :         std::list< SvtLinguConfigDictionaryEntry > aDics;
     172         [ +  - ]:         46 :         uno::Sequence< rtl::OUString > aFormatList;
     173                 :            :         aLinguCfg.GetSupportedDictionaryFormatsFor( A2OU("Thesauri"),
     174 [ +  - ][ +  - ]:         46 :                 A2OU("org.openoffice.lingu.new.Thesaurus"), aFormatList );
                 [ +  - ]
     175                 :         46 :         sal_Int32 nLen = aFormatList.getLength();
     176         [ +  + ]:         92 :         for (sal_Int32 i = 0;  i < nLen;  ++i)
     177                 :            :         {
     178                 :            :             std::vector< SvtLinguConfigDictionaryEntry > aTmpDic(
     179 [ +  - ][ +  - ]:         46 :                     aLinguCfg.GetActiveDictionariesByFormat( aFormatList[i] ) );
     180         [ +  - ]:         46 :             aDics.insert( aDics.end(), aTmpDic.begin(), aTmpDic.end() );
     181                 :         46 :         }
     182                 :            : 
     183                 :            :         //!! for compatibility with old dictionaries (the ones not using extensions
     184                 :            :         //!! or new configuration entries, but still using the dictionary.lst file)
     185                 :            :         //!! Get the list of old style spell checking dictionaries to use...
     186                 :            :         std::vector< SvtLinguConfigDictionaryEntry > aOldStyleDics(
     187         [ +  - ]:         46 :                 GetOldStyleDics( "THES" ) );
     188                 :            : 
     189                 :            :         // to prefer dictionaries with configuration entries we will only
     190                 :            :         // use those old style dictionaries that add a language that
     191                 :            :         // is not yet supported by the list od new style dictionaries
     192         [ +  - ]:         46 :         MergeNewStyleDicsAndOldStyleDics( aDics, aOldStyleDics );
     193                 :            : 
     194                 :         46 :         numthes = aDics.size();
     195         [ +  - ]:         46 :         if (numthes)
     196                 :            :         {
     197                 :            :             // get supported locales from the dictionaries-to-use...
     198                 :         46 :             sal_Int32 k = 0;
     199         [ +  - ]:         46 :             std::set< rtl::OUString, lt_rtl_OUString > aLocaleNamesSet;
     200         [ +  - ]:         46 :             std::list< SvtLinguConfigDictionaryEntry >::const_iterator aDictIt;
     201 [ +  - ][ +  - ]:        276 :             for (aDictIt = aDics.begin();  aDictIt != aDics.end();  ++aDictIt)
         [ +  - ][ +  - ]
                 [ +  + ]
     202                 :            :             {
     203 [ +  - ][ +  - ]:        230 :                 uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
     204                 :        230 :                 sal_Int32 nLen2 = aLocaleNames.getLength();
     205         [ +  + ]:       2300 :                 for (k = 0;  k < nLen2;  ++k)
     206                 :            :                 {
     207 [ +  - ][ +  - ]:       2070 :                     aLocaleNamesSet.insert( aLocaleNames[k] );
     208                 :            :                 }
     209         [ +  - ]:        230 :             }
     210                 :            :             // ... and add them to the resulting sequence
     211         [ +  - ]:         46 :             aSuppLocales.realloc( aLocaleNamesSet.size() );
     212                 :         46 :             std::set< rtl::OUString, lt_rtl_OUString >::const_iterator aItB;
     213                 :         46 :             k = 0;
     214         [ +  + ]:       2116 :             for (aItB = aLocaleNamesSet.begin();  aItB != aLocaleNamesSet.end();  ++aItB)
     215                 :            :             {
     216                 :            :                 Locale aTmp( MsLangId::convertLanguageToLocale(
     217 [ +  - ][ +  - ]:       2070 :                         MsLangId::convertIsoStringToLanguage( *aItB )));
     218         [ +  - ]:       2070 :                 aSuppLocales[k++] = aTmp;
     219                 :       2070 :             }
     220                 :            : 
     221                 :            :             //! For each dictionary and each locale we need a seperate entry.
     222                 :            :             //! If this results in more than one dictionary per locale than (for now)
     223                 :            :             //! it is undefined which dictionary gets used.
     224                 :            :             //! In the future the implementation should support using several dictionaries
     225                 :            :             //! for one locale.
     226                 :         46 :             numthes = 0;
     227 [ +  - ][ +  - ]:        276 :             for (aDictIt = aDics.begin();  aDictIt != aDics.end();  ++aDictIt)
         [ +  - ][ +  - ]
                 [ +  + ]
     228         [ +  - ]:        230 :                 numthes = numthes + aDictIt->aLocaleNames.getLength();
     229                 :            : 
     230                 :            :             // add dictionary information
     231         [ +  - ]:         46 :             aThes   = new MyThes* [numthes];
     232         [ +  - ]:         46 :             aTEncs  = new rtl_TextEncoding [numthes];
     233 [ +  - ][ +  + ]:       2116 :             aTLocs  = new Locale [numthes];
     234 [ +  - ][ +  + ]:       2116 :             aTNames = new OUString [numthes];
     235         [ +  - ]:         46 :             aCharSetInfo = new CharClass* [numthes];
     236                 :            : 
     237                 :         46 :             k = 0;
     238 [ +  - ][ +  - ]:        276 :             for (aDictIt = aDics.begin();  aDictIt != aDics.end();  ++aDictIt)
         [ +  - ][ +  - ]
                 [ +  + ]
     239                 :            :             {
     240         [ +  - ]:        460 :                 if (aDictIt->aLocaleNames.getLength() > 0 &&
           [ +  -  +  - ]
                 [ +  - ]
     241         [ +  - ]:        230 :                     aDictIt->aLocations.getLength() > 0)
     242                 :            :                 {
     243 [ +  - ][ +  - ]:        230 :                     uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
     244                 :        230 :                     sal_Int32 nLocales = aLocaleNames.getLength();
     245                 :            : 
     246                 :            :                     // currently only one language per dictionary is supported in the actual implementation...
     247                 :            :                     // Thus here we work-around this by adding the same dictionary several times.
     248                 :            :                     // Once for each of it's supported locales.
     249         [ +  + ]:       2300 :                     for (sal_Int32 i = 0;  i < nLocales;  ++i)
     250                 :            :                     {
     251                 :       2070 :                         aThes[k]  = NULL;
     252                 :       2070 :                         aTEncs[k]  = RTL_TEXTENCODING_DONTKNOW;
     253                 :            :                         aTLocs[k]  = MsLangId::convertLanguageToLocale(
     254 [ +  - ][ +  - ]:       2070 :                                         MsLangId::convertIsoStringToLanguage( aDictIt->aLocaleNames[i] ));
                 [ +  - ]
     255 [ +  - ][ +  - ]:       2070 :                         aCharSetInfo[k] = new CharClass( aTLocs[k] );
     256                 :            :                         // also both files have to be in the same directory and the
     257                 :            :                         // file names must only differ in the extension (.aff/.dic).
     258                 :            :                         // Thus we use the first location only and strip the extension part.
     259         [ +  - ]:       2070 :                         rtl::OUString aLocation = aDictIt->aLocations[0];
     260                 :       2070 :                         sal_Int32 nPos = aLocation.lastIndexOf( '.' );
     261                 :       2070 :                         aLocation = aLocation.copy( 0, nPos );
     262                 :       2070 :                         aTNames[k] = aLocation;
     263                 :            : 
     264                 :       2070 :                         ++k;
     265         [ +  - ]:       2300 :                     }
     266                 :            :                 }
     267                 :            :             }
     268                 :         46 :             DBG_ASSERT( k == numthes, "index mismatch?" );
     269                 :            :         }
     270                 :            :         else
     271                 :            :         {
     272                 :            :             /* no dictionary found so register no dictionaries */
     273                 :          0 :             numthes = 0;
     274                 :          0 :             aThes  = NULL;
     275                 :          0 :             aTEncs  = NULL;
     276                 :          0 :             aTLocs  = NULL;
     277                 :          0 :             aTNames = NULL;
     278                 :          0 :             aCharSetInfo = NULL;
     279         [ #  # ]:          0 :             aSuppLocales.realloc(0);
     280 [ +  - ][ +  - ]:         46 :         }
     281                 :            :     }
     282                 :            : 
     283 [ +  - ][ +  - ]:         96 :     return aSuppLocales;
     284                 :            : }
     285                 :            : 
     286                 :            : 
     287                 :            : 
     288                 :          0 : sal_Bool SAL_CALL Thesaurus::hasLocale(const Locale& rLocale)
     289                 :            :         throw(RuntimeException)
     290                 :            : {
     291 [ #  # ][ #  # ]:          0 :     MutexGuard  aGuard( GetLinguMutex() );
     292                 :            : 
     293                 :          0 :     sal_Bool bRes = sal_False;
     294         [ #  # ]:          0 :     if (!aSuppLocales.getLength())
     295 [ #  # ][ #  # ]:          0 :         getLocales();
     296                 :          0 :     sal_Int32 nLen = aSuppLocales.getLength();
     297         [ #  # ]:          0 :     for (sal_Int32 i = 0;  i < nLen;  ++i)
     298                 :            :     {
     299                 :          0 :         const Locale *pLocale = aSuppLocales.getConstArray();
     300         [ #  # ]:          0 :         if (rLocale == pLocale[i])
     301                 :            :         {
     302                 :          0 :             bRes = sal_True;
     303                 :          0 :             break;
     304                 :            :         }
     305                 :            :     }
     306         [ #  # ]:          0 :     return bRes;
     307                 :            : }
     308                 :            : 
     309                 :            : 
     310                 :          0 : Sequence < Reference < ::com::sun::star::linguistic2::XMeaning > > SAL_CALL Thesaurus::queryMeanings(
     311                 :            :     const OUString& qTerm, const Locale& rLocale,
     312                 :            :     const PropertyValues& rProperties)
     313                 :            :     throw(IllegalArgumentException, RuntimeException)
     314                 :            : {
     315 [ #  # ][ #  # ]:          0 :     MutexGuard      aGuard( GetLinguMutex() );
     316                 :            : 
     317         [ #  # ]:          0 :     uno::Sequence< Reference< XMeaning > > aMeanings( 1 );
     318         [ #  # ]:          0 :     uno::Sequence< Reference< XMeaning > > noMeanings( 0 );
     319         [ #  # ]:          0 :     uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
     320                 :          0 :     uno::Reference< XSpellChecker1 > xSpell;
     321                 :            : 
     322                 :          0 :     OUString rTerm(qTerm);
     323                 :          0 :     OUString pTerm(qTerm);
     324                 :          0 :     sal_uInt16 ct = CAPTYPE_UNKNOWN;
     325                 :          0 :     sal_Int32 stem = 0;
     326                 :          0 :     sal_Int32 stem2 = 0;
     327                 :            : 
     328         [ #  # ]:          0 :     sal_Int16 nLanguage = LocaleToLanguage( rLocale );
     329                 :            : 
     330 [ #  # ][ #  # ]:          0 :     if (nLanguage == LANGUAGE_NONE || rTerm.isEmpty())
                 [ #  # ]
     331         [ #  # ]:          0 :         return noMeanings;
     332                 :            : 
     333 [ #  # ][ #  # ]:          0 :     if (!hasLocale( rLocale ))
     334                 :            : #ifdef LINGU_EXCEPTIONS
     335                 :            :         throw( IllegalArgumentException() );
     336                 :            : #else
     337         [ #  # ]:          0 :         return noMeanings;
     338                 :            : #endif
     339                 :            : 
     340 [ #  # ][ #  # ]:          0 :     if (prevTerm == qTerm && prevLocale == nLanguage)
                 [ #  # ]
     341         [ #  # ]:          0 :         return prevMeanings;
     342                 :            : 
     343                 :          0 :     mentry * pmean = NULL;
     344                 :          0 :     sal_Int32 nmean = 0;
     345                 :            : 
     346         [ #  # ]:          0 :     PropertyHelper_Thesaurus &rHelper = GetPropHelper();
     347         [ #  # ]:          0 :     rHelper.SetTmpPropVals( rProperties );
     348                 :            : 
     349                 :          0 :     MyThes * pTH = NULL;
     350                 :          0 :     rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
     351                 :          0 :     CharClass * pCC = NULL;
     352                 :            : 
     353                 :            :     // find the first thesaurus that matches the locale
     354         [ #  # ]:          0 :     for (int i =0; i < numthes; i++)
     355                 :            :     {
     356         [ #  # ]:          0 :         if (rLocale == aTLocs[i])
     357                 :            :         {
     358                 :            :             // open up and intialize this thesaurus if need be
     359         [ #  # ]:          0 :             if (!aThes[i])
     360                 :            :             {
     361         [ #  # ]:          0 :                 OUString datpath = aTNames[i] + A2OU(".dat");
     362         [ #  # ]:          0 :                 OUString idxpath = aTNames[i] + A2OU(".idx");
     363                 :          0 :                 OUString ndat;
     364                 :          0 :                 OUString nidx;
     365         [ #  # ]:          0 :                 osl::FileBase::getSystemPathFromFileURL(datpath,ndat);
     366         [ #  # ]:          0 :                 osl::FileBase::getSystemPathFromFileURL(idxpath,nidx);
     367 [ #  # ][ #  # ]:          0 :                 OString aTmpidx(OU2ENC(nidx,osl_getThreadTextEncoding()));
     368 [ #  # ][ #  # ]:          0 :                 OString aTmpdat(OU2ENC(ndat,osl_getThreadTextEncoding()));
     369                 :            : 
     370                 :            : #if defined(WNT)
     371                 :            :                 // workaround for Windows specifc problem that the
     372                 :            :                 // path length in calls to 'fopen' is limted to somewhat
     373                 :            :                 // about 120+ characters which will usually be exceed when
     374                 :            :                 // using dictionaries as extensions.
     375                 :            :                 aTmpidx = Win_GetShortPathName( nidx );
     376                 :            :                 aTmpdat = Win_GetShortPathName( ndat );
     377                 :            : #endif
     378                 :            : 
     379 [ #  # ][ #  # ]:          0 :                 aThes[i] = new MyThes(aTmpidx.getStr(),aTmpdat.getStr());
     380         [ #  # ]:          0 :                 if (aThes[i])
     381 [ #  # ][ #  # ]:          0 :                     aTEncs[i] = getTextEncodingFromCharset(aThes[i]->get_th_encoding());
     382                 :            :             }
     383                 :          0 :             pTH = aThes[i];
     384                 :          0 :             eEnc = aTEncs[i];
     385                 :          0 :             pCC = aCharSetInfo[i];
     386                 :            : 
     387         [ #  # ]:          0 :             if (pTH)
     388                 :          0 :                 break;
     389                 :            :         }
     390                 :            :     }
     391                 :            : 
     392                 :            :     // we don't want to work with a default text encoding since following incorrect
     393                 :            :     // results may occur only for specific text and thus may be hard to notice.
     394                 :            :     // Thus better always make a clean exit here if the text encoding is in question.
     395                 :            :     // Hopefully something not working at all will raise proper attention quickly. ;-)
     396                 :            :     DBG_ASSERT( eEnc != RTL_TEXTENCODING_DONTKNOW, "failed to get text encoding! (maybe incorrect encoding string in file)" );
     397         [ #  # ]:          0 :     if (eEnc == RTL_TEXTENCODING_DONTKNOW)
     398         [ #  # ]:          0 :         return noMeanings;
     399                 :            : 
     400         [ #  # ]:          0 :     while (pTH)
     401                 :            :     {
     402                 :            :         // convert word to all lower case for searching
     403         [ #  # ]:          0 :         if (!stem)
     404         [ #  # ]:          0 :             ct = capitalType(rTerm, pCC);
     405         [ #  # ]:          0 :         OUString nTerm(makeLowerCase(rTerm, pCC));
     406         [ #  # ]:          0 :         OString aTmp( OU2ENC(nTerm, eEnc) );
     407         [ #  # ]:          0 :         nmean = pTH->Lookup(aTmp.getStr(),aTmp.getLength(),&pmean);
     408                 :            : 
     409         [ #  # ]:          0 :         if (nmean)
     410         [ #  # ]:          0 :             aMeanings.realloc( nmean );
     411                 :            : 
     412                 :          0 :         mentry * pe = pmean;
     413                 :          0 :         OUString codeTerm = qTerm;
     414                 :          0 :         Reference< XSpellAlternatives > xTmpRes2;
     415                 :            : 
     416         [ #  # ]:          0 :         if (stem)
     417                 :            :         {
     418         [ #  # ]:          0 :             xTmpRes2 = xSpell->spell( A2OU("<?xml?><query type='analyze'><word>") +
     419 [ #  # ][ #  # ]:          0 :             pTerm + A2OU("</word></query>"), nLanguage, rProperties );
         [ #  # ][ #  # ]
     420         [ #  # ]:          0 :             if (xTmpRes2.is())
     421                 :            :             {
     422 [ #  # ][ #  # ]:          0 :                 Sequence<OUString>seq = xTmpRes2->getAlternatives();
     423         [ #  # ]:          0 :                 if (seq.getLength() > 0)
     424                 :            :                 {
     425         [ #  # ]:          0 :                     codeTerm = seq[0];
     426                 :          0 :                     stem2 = 1;
     427         [ #  # ]:          0 :                 }
     428                 :            : #if 0
     429                 :            :                 OString o = OUStringToOString(codeTerm, RTL_TEXTENCODING_UTF8);
     430                 :            :                 fprintf(stderr, "CODETERM: %s\n", o.pData->buffer);
     431                 :            : #endif
     432                 :            :             }
     433                 :            :         }
     434                 :            : 
     435         [ #  # ]:          0 :         for (int j = 0; j < nmean; j++)
     436                 :            :         {
     437                 :          0 :             int count = pe->count;
     438         [ #  # ]:          0 :             if (count)
     439                 :            :             {
     440         [ #  # ]:          0 :                 Sequence< OUString > aStr( count );
     441         [ #  # ]:          0 :                 OUString *pStr = aStr.getArray();
     442                 :            : 
     443         [ #  # ]:          0 :                 for (int i=0; i < count; i++)
     444                 :            :                 {
     445         [ #  # ]:          0 :                     OUString sTerm(pe->psyns[i],strlen(pe->psyns[i]),eEnc );
     446                 :          0 :                     sal_Int32 catpos = sTerm.indexOf('(');
     447                 :          0 :                     sal_Int32 catpos2 = 0;
     448                 :          0 :                     OUString catst;
     449                 :          0 :                     OUString catst2;
     450         [ #  # ]:          0 :                     if (catpos > 2)
     451                 :            :                     {
     452                 :            :                         // remove category name for affixation and casing
     453         [ #  # ]:          0 :                         catst = A2OU(" ") + sTerm.copy(catpos);
     454                 :          0 :                         sTerm = sTerm.copy(0, catpos);
     455                 :          0 :                         sTerm = sTerm.trim();
     456                 :            :                     }
     457                 :            :                     // generate synonyms with affixes
     458 [ #  # ][ #  # ]:          0 :                     if (stem && stem2)
     459                 :            :                     {
     460                 :          0 :                         Reference< XSpellAlternatives > xTmpRes;
     461         [ #  # ]:          0 :                         xTmpRes = xSpell->spell( A2OU("<?xml?><query type='generate'><word>") +
     462 [ #  # ][ #  # ]:          0 :                         sTerm + A2OU("</word>") + codeTerm + A2OU("</query>"), nLanguage, rProperties );
         [ #  # ][ #  # ]
                 [ #  # ]
     463         [ #  # ]:          0 :                         if (xTmpRes.is())
     464                 :            :                         {
     465 [ #  # ][ #  # ]:          0 :                             Sequence<OUString>seq = xTmpRes->getAlternatives();
     466         [ #  # ]:          0 :                             if (seq.getLength() > 0)
     467 [ #  # ][ #  # ]:          0 :                                 sTerm = seq[0];
     468                 :          0 :                         }
     469                 :            :                     }
     470         [ #  # ]:          0 :                     if (catpos2)
     471                 :          0 :                         sTerm = catst2 + sTerm;
     472                 :            : 
     473         [ #  # ]:          0 :                     sal_uInt16 ct1 = capitalType(sTerm, pCC);
     474         [ #  # ]:          0 :                     if (CAPTYPE_MIXED == ct1)
     475                 :          0 :                         ct = ct1;
     476                 :          0 :                     OUString cTerm;
     477      [ #  #  # ]:          0 :                     switch (ct)
     478                 :            :                     {
     479                 :            :                         case CAPTYPE_ALLCAP:
     480         [ #  # ]:          0 :                             cTerm = makeUpperCase(sTerm, pCC);
     481                 :          0 :                             break;
     482                 :            :                         case CAPTYPE_INITCAP:
     483         [ #  # ]:          0 :                             cTerm = makeInitCap(sTerm, pCC);
     484                 :          0 :                             break;
     485                 :            :                         default:
     486                 :          0 :                             cTerm = sTerm;
     487                 :          0 :                             break;
     488                 :            :                     }
     489                 :          0 :                     OUString aAlt( cTerm + catst);
     490                 :          0 :                     pStr[i] = aAlt;
     491                 :          0 :                 }
     492                 :            : #if 0
     493                 :            :                 Meaning * pMn = new Meaning(rTerm,nLanguage,rHelper);
     494                 :            : #endif
     495         [ #  # ]:          0 :                 Meaning * pMn = new Meaning(rTerm,nLanguage);
     496         [ #  # ]:          0 :                 OUString dTerm(pe->defn,strlen(pe->defn),eEnc );
     497         [ #  # ]:          0 :                 pMn->SetMeaning(dTerm);
     498         [ #  # ]:          0 :                 pMn->SetSynonyms(aStr);
     499         [ #  # ]:          0 :                 Reference<XMeaning>* pMeaning = aMeanings.getArray();
     500 [ #  # ][ #  # ]:          0 :                 pMeaning[j] = pMn;
                 [ #  # ]
     501                 :            :             }
     502                 :          0 :             pe++;
     503                 :            :         }
     504         [ #  # ]:          0 :         pTH->CleanUpAfterLookup(&pmean,nmean);
     505                 :            : 
     506         [ #  # ]:          0 :         if (nmean)
     507                 :            :         {
     508                 :          0 :             prevTerm = qTerm;
     509         [ #  # ]:          0 :             prevMeanings = aMeanings;
     510                 :          0 :             prevLocale = nLanguage;
     511         [ #  # ]:          0 :             return aMeanings;
     512                 :            :         }
     513                 :            : 
     514 [ #  # ][ #  # ]:          0 :         if (stem || !xLngSvcMgr.is())
                 [ #  # ]
     515         [ #  # ]:          0 :             return noMeanings;
     516                 :          0 :         stem = 1;
     517                 :            : 
     518 [ #  # ][ #  # ]:          0 :         xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
         [ #  # ][ #  # ]
     519 [ #  # ][ #  # ]:          0 :         if (!xSpell.is() || !xSpell->isValid( A2OU(SPELLML_SUPPORT), nLanguage, rProperties ))
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     520         [ #  # ]:          0 :             return noMeanings;
     521                 :          0 :         Reference< XSpellAlternatives > xTmpRes;
     522         [ #  # ]:          0 :         xTmpRes = xSpell->spell( A2OU("<?xml?><query type='stem'><word>") +
     523 [ #  # ][ #  # ]:          0 :             rTerm + A2OU("</word></query>"), nLanguage, rProperties );
         [ #  # ][ #  # ]
     524         [ #  # ]:          0 :         if (xTmpRes.is())
     525                 :            :         {
     526 [ #  # ][ #  # ]:          0 :             Sequence<OUString>seq = xTmpRes->getAlternatives();
     527                 :            : #if 0
     528                 :            :             for (int i = 0; i < seq.getLength(); i++)
     529                 :            :             {
     530                 :            :                 OString o = OUStringToOString(seq[i], RTL_TEXTENCODING_UTF8);
     531                 :            :                 fprintf(stderr, "%d: %s\n", i + 1, o.pData->buffer);
     532                 :            :             }
     533                 :            : #endif
     534         [ #  # ]:          0 :             if (seq.getLength() > 0)
     535                 :            :             {
     536         [ #  # ]:          0 :                 rTerm = seq[0];  // XXX Use only the first stem
     537                 :          0 :                 continue;
     538 [ #  # ][ #  # ]:          0 :             }
     539                 :            :         }
     540                 :            : 
     541                 :            :         // stem the last word of the synonym (for categories after affixation)
     542                 :          0 :         rTerm = rTerm.trim();
     543                 :          0 :         sal_Int32 pos = rTerm.lastIndexOf(' ');
     544         [ #  # ]:          0 :         if (!pos)
     545         [ #  # ]:          0 :             return noMeanings;
     546         [ #  # ]:          0 :         xTmpRes = xSpell->spell( A2OU("<?xml?><query type='stem'><word>") +
     547 [ #  # ][ #  # ]:          0 :             rTerm.copy(pos + 1) + A2OU("</word></query>"), nLanguage, rProperties );
         [ #  # ][ #  # ]
     548         [ #  # ]:          0 :         if (xTmpRes.is())
     549                 :            :         {
     550 [ #  # ][ #  # ]:          0 :             Sequence<OUString>seq = xTmpRes->getAlternatives();
     551         [ #  # ]:          0 :             if (seq.getLength() > 0)
     552                 :            :             {
     553                 :          0 :                 pTerm = rTerm.copy(pos + 1);
     554         [ #  # ]:          0 :                 rTerm = rTerm.copy(0, pos + 1) + seq[0];
     555                 :            : #if  0
     556                 :            :                 for (int i = 0; i < seq.getLength(); i++)
     557                 :            :                 {
     558                 :            :                     OString o = OUStringToOString(seq[i], RTL_TEXTENCODING_UTF8);
     559                 :            :                     fprintf(stderr, "%d: %s\n", i + 1, o.pData->buffer);
     560                 :            :                 }
     561                 :            : #endif
     562                 :          0 :                 continue;
     563 [ #  # ][ #  # ]:          0 :             }
     564                 :            :         }
     565      [ #  #  # ]:          0 :         break;
     566      [ #  #  # ]:          0 :     }
              [ #  #  # ]
              [ #  #  # ]
              [ #  #  # ]
     567 [ #  # ][ #  # ]:          0 :     return noMeanings;
         [ #  # ][ #  # ]
     568                 :            : }
     569                 :            : 
     570                 :            : 
     571                 :         46 : Reference< XInterface > SAL_CALL Thesaurus_CreateInstance(
     572                 :            :             const Reference< XMultiServiceFactory > & /*rSMgr*/ )
     573                 :            :         throw(Exception)
     574                 :            : {
     575 [ +  - ][ +  - ]:         46 :     Reference< XInterface > xService = (cppu::OWeakObject*) new Thesaurus;
     576                 :         46 :     return xService;
     577                 :            : }
     578                 :            : 
     579                 :            : 
     580                 :          0 : OUString SAL_CALL Thesaurus::getServiceDisplayName( const Locale& /*rLocale*/ )
     581                 :            :         throw(RuntimeException)
     582                 :            : {
     583 [ #  # ][ #  # ]:          0 :     MutexGuard  aGuard( GetLinguMutex() );
     584 [ #  # ][ #  # ]:          0 :     return A2OU( "OpenOffice.org New Thesaurus" );
     585                 :            : }
     586                 :            : 
     587                 :            : 
     588                 :          0 : void SAL_CALL Thesaurus::initialize( const Sequence< Any >& rArguments )
     589                 :            :         throw(Exception, RuntimeException)
     590                 :            : {
     591 [ #  # ][ #  # ]:          0 :     MutexGuard  aGuard( GetLinguMutex() );
     592                 :            : 
     593         [ #  # ]:          0 :     if (!pPropHelper)
     594                 :            :     {
     595                 :          0 :         sal_Int32 nLen = rArguments.getLength();
     596         [ #  # ]:          0 :         if (1 == nLen)
     597                 :            :         {
     598                 :          0 :             Reference< XPropertySet >   xPropSet;
     599         [ #  # ]:          0 :             rArguments.getConstArray()[0] >>= xPropSet;
     600                 :            : 
     601                 :            :             //! Pointer allows for access of the non-UNO functions.
     602                 :            :             //! And the reference to the UNO-functions while increasing
     603                 :            :             //! the ref-count and will implicitly free the memory
     604                 :            :             //! when the object is not longer used.
     605 [ #  # ][ #  # ]:          0 :             pPropHelper = new PropertyHelper_Thesaurus( (XThesaurus *) this, xPropSet );
                 [ #  # ]
     606         [ #  # ]:          0 :             pPropHelper->AddAsPropListener();   //! after a reference is established
     607                 :            :         }
     608                 :            :         else
     609                 :            :             OSL_FAIL( "wrong number of arguments in sequence" );
     610         [ #  # ]:          0 :     }
     611                 :          0 : }
     612                 :            : 
     613                 :            : 
     614                 :            : 
     615                 :          0 : sal_uInt16 SAL_CALL Thesaurus::capitalType(const OUString& aTerm, CharClass * pCC)
     616                 :            : {
     617                 :          0 :         sal_Int32 tlen = aTerm.getLength();
     618 [ #  # ][ #  # ]:          0 :         if ((pCC) && (tlen))
     619                 :            :         {
     620         [ #  # ]:          0 :             String aStr(aTerm);
     621                 :          0 :             sal_Int32 nc = 0;
     622         [ #  # ]:          0 :             for (sal_uInt16 tindex = 0; tindex < tlen;  tindex++)
     623                 :            :             {
     624 [ #  # ][ #  # ]:          0 :                 if (pCC->getCharacterType(aStr,tindex) &
     625                 :          0 :                    ::com::sun::star::i18n::KCharacterType::UPPER) nc++;
     626                 :            :             }
     627                 :            : 
     628         [ #  # ]:          0 :             if (nc == 0)
     629                 :          0 :                 return (sal_uInt16) CAPTYPE_NOCAP;
     630         [ #  # ]:          0 :             if (nc == tlen)
     631                 :          0 :                 return (sal_uInt16) CAPTYPE_ALLCAP;
     632 [ #  # ][ #  # ]:          0 :             if ((nc == 1) && (pCC->getCharacterType(aStr,0) &
         [ #  # ][ #  # ]
     633                 :            :                   ::com::sun::star::i18n::KCharacterType::UPPER))
     634                 :          0 :                 return (sal_uInt16) CAPTYPE_INITCAP;
     635                 :            : 
     636         [ #  # ]:          0 :             return (sal_uInt16) CAPTYPE_MIXED;
     637                 :            :         }
     638                 :          0 :         return (sal_uInt16) CAPTYPE_UNKNOWN;
     639                 :            : }
     640                 :            : 
     641                 :            : 
     642                 :            : 
     643                 :          0 : OUString SAL_CALL Thesaurus::makeLowerCase(const OUString& aTerm, CharClass * pCC)
     644                 :            : {
     645         [ #  # ]:          0 :     if (pCC)
     646                 :          0 :         return pCC->lowercase(aTerm);
     647                 :          0 :     return aTerm;
     648                 :            : }
     649                 :            : 
     650                 :            : 
     651                 :          0 : OUString SAL_CALL Thesaurus::makeUpperCase(const OUString& aTerm, CharClass * pCC)
     652                 :            : {
     653         [ #  # ]:          0 :     if (pCC)
     654                 :          0 :         return pCC->uppercase(aTerm);
     655                 :          0 :     return aTerm;
     656                 :            : }
     657                 :            : 
     658                 :            : 
     659                 :          0 : OUString SAL_CALL Thesaurus::makeInitCap(const OUString& aTerm, CharClass * pCC)
     660                 :            : {
     661                 :          0 :     sal_Int32 tlen = aTerm.getLength();
     662 [ #  # ][ #  # ]:          0 :     if ((pCC) && (tlen))
     663                 :            :     {
     664                 :          0 :         OUString bTemp = aTerm.copy(0,1);
     665         [ #  # ]:          0 :         if (tlen > 1)
     666                 :            :         {
     667                 :            :             return ( pCC->uppercase(bTemp, 0, 1)
     668 [ #  # ][ #  # ]:          0 :                      + pCC->lowercase(aTerm,1,(tlen-1)) );
     669                 :            :         }
     670                 :            : 
     671         [ #  # ]:          0 :         return pCC->uppercase(bTemp, 0, 1);
     672                 :            :     }
     673                 :          0 :     return aTerm;
     674                 :            : }
     675                 :            : 
     676                 :            : 
     677                 :            : 
     678                 :         46 : void SAL_CALL Thesaurus::dispose()
     679                 :            :         throw(RuntimeException)
     680                 :            : {
     681 [ +  - ][ +  - ]:         46 :     MutexGuard  aGuard( GetLinguMutex() );
     682                 :            : 
     683         [ +  - ]:         46 :     if (!bDisposing)
     684                 :            :     {
     685                 :         46 :         bDisposing = sal_True;
     686 [ +  - ][ +  - ]:         46 :         EventObject aEvtObj( (XThesaurus *) this );
     687         [ +  - ]:         46 :         aEvtListeners.disposeAndClear( aEvtObj );
     688         [ -  + ]:         46 :         if (pPropHelper)
     689                 :            :         {
     690         [ #  # ]:          0 :             pPropHelper->RemoveAsPropListener();
     691 [ #  # ][ #  # ]:          0 :             delete pPropHelper;
     692                 :          0 :             pPropHelper = NULL;
     693         [ +  - ]:         46 :         }
     694         [ +  - ]:         46 :     }
     695                 :         46 : }
     696                 :            : 
     697                 :            : 
     698                 :          0 : void SAL_CALL Thesaurus::addEventListener( const Reference< XEventListener >& rxListener )
     699                 :            :         throw(RuntimeException)
     700                 :            : {
     701 [ #  # ][ #  # ]:          0 :     MutexGuard  aGuard( GetLinguMutex() );
     702                 :            : 
     703 [ #  # ][ #  # ]:          0 :     if (!bDisposing && rxListener.is())
                 [ #  # ]
     704 [ #  # ][ #  # ]:          0 :         aEvtListeners.addInterface( rxListener );
     705                 :          0 : }
     706                 :            : 
     707                 :            : 
     708                 :          0 : void SAL_CALL Thesaurus::removeEventListener( const Reference< XEventListener >& rxListener )
     709                 :            :         throw(RuntimeException)
     710                 :            : {
     711 [ #  # ][ #  # ]:          0 :     MutexGuard  aGuard( GetLinguMutex() );
     712                 :            : 
     713 [ #  # ][ #  # ]:          0 :     if (!bDisposing && rxListener.is())
                 [ #  # ]
     714 [ #  # ][ #  # ]:          0 :         aEvtListeners.removeInterface( rxListener );
     715                 :          0 : }
     716                 :            : 
     717                 :            : 
     718                 :            : ///////////////////////////////////////////////////////////////////////////
     719                 :            : // Service specific part
     720                 :            : //
     721                 :            : 
     722                 :         48 : OUString SAL_CALL Thesaurus::getImplementationName()
     723                 :            :         throw(RuntimeException)
     724                 :            : {
     725 [ +  - ][ +  - ]:         48 :     MutexGuard  aGuard( GetLinguMutex() );
     726         [ +  - ]:         48 :     return getImplementationName_Static();
     727                 :            : }
     728                 :            : 
     729                 :            : 
     730                 :          0 : sal_Bool SAL_CALL Thesaurus::supportsService( const OUString& ServiceName )
     731                 :            :         throw(RuntimeException)
     732                 :            : {
     733 [ #  # ][ #  # ]:          0 :     MutexGuard  aGuard( GetLinguMutex() );
     734                 :            : 
     735         [ #  # ]:          0 :     Sequence< OUString > aSNL = getSupportedServiceNames();
     736                 :          0 :     const OUString * pArray = aSNL.getConstArray();
     737         [ #  # ]:          0 :     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
     738         [ #  # ]:          0 :         if( pArray[i] == ServiceName )
     739                 :          0 :             return sal_True;
     740 [ #  # ][ #  # ]:          0 :     return sal_False;
     741                 :            : }
     742                 :            : 
     743                 :            : 
     744                 :          0 : Sequence< OUString > SAL_CALL Thesaurus::getSupportedServiceNames()
     745                 :            :         throw(RuntimeException)
     746                 :            : {
     747 [ #  # ][ #  # ]:          0 :     MutexGuard  aGuard( GetLinguMutex() );
     748         [ #  # ]:          0 :     return getSupportedServiceNames_Static();
     749                 :            : }
     750                 :            : 
     751                 :            : 
     752                 :         46 : Sequence< OUString > Thesaurus::getSupportedServiceNames_Static()
     753                 :            :         throw()
     754                 :            : {
     755 [ +  - ][ +  - ]:         46 :     MutexGuard  aGuard( GetLinguMutex() );
     756                 :            : 
     757         [ +  - ]:         46 :     Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
     758 [ +  - ][ +  - ]:         46 :     aSNS.getArray()[0] = A2OU( SN_THESAURUS );
     759         [ +  - ]:         46 :     return aSNS;
     760                 :            : }
     761                 :            : 
     762                 :         46 : void * SAL_CALL Thesaurus_getFactory( const sal_Char * pImplName,
     763                 :            :             XMultiServiceFactory * pServiceManager, void *  )
     764                 :            : {
     765                 :         46 :     void * pRet = 0;
     766         [ +  - ]:         46 :     if ( !Thesaurus::getImplementationName_Static().compareToAscii( pImplName ) )
     767                 :            :     {
     768                 :            : 
     769                 :            :         Reference< XSingleServiceFactory > xFactory =
     770                 :            :             cppu::createOneInstanceFactory(
     771                 :            :                 pServiceManager,
     772                 :            :                 Thesaurus::getImplementationName_Static(),
     773                 :            :                 Thesaurus_CreateInstance,
     774 [ +  - ][ +  - ]:         46 :                 Thesaurus::getSupportedServiceNames_Static());
                 [ +  - ]
     775                 :            :         // acquire, because we return an interface pointer instead of a reference
     776         [ +  - ]:         46 :         xFactory->acquire();
     777         [ +  - ]:         46 :         pRet = xFactory.get();
     778                 :            :     }
     779                 :         46 :     return pRet;
     780                 :            : }
     781                 :            : 
     782                 :            : 
     783                 :            : ///////////////////////////////////////////////////////////////////////////
     784                 :            : 
     785                 :            : 
     786                 :            : #undef CAPTYPE_UNKNOWN
     787                 :            : #undef CAPTYPE_NOCAP
     788                 :            : #undef CAPTYPE_INITCAP
     789                 :            : #undef CAPTYPE_ALLCAP
     790                 :            : #undef CAPTYPE_MIXED
     791                 :            : 
     792                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10