1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_linguistic.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <tools/fsys.hxx> 32*cdf0e10cSrcweir #include <tools/stream.hxx> 33*cdf0e10cSrcweir #include <tools/urlobj.hxx> 34*cdf0e10cSrcweir #include <unotools/pathoptions.hxx> 35*cdf0e10cSrcweir #include <unotools/useroptions.hxx> 36*cdf0e10cSrcweir #include <unotools/lingucfg.hxx> 37*cdf0e10cSrcweir #include <rtl/instance.hxx> 38*cdf0e10cSrcweir #include <cppuhelper/factory.hxx> // helper for factories 39*cdf0e10cSrcweir #include <unotools/localfilehelper.hxx> 40*cdf0e10cSrcweir #include <com/sun/star/linguistic2/XConversionDictionaryList.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/linguistic2/XConversionDictionary.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/util/XFlushable.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp> 45*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_UNO_REFERENCE_HPP_ 46*cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h> 47*cdf0e10cSrcweir #endif 48*cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp> 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #include <ucbhelper/content.hxx> 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #include "convdiclist.hxx" 54*cdf0e10cSrcweir #include "convdic.hxx" 55*cdf0e10cSrcweir #include "hhconvdic.hxx" 56*cdf0e10cSrcweir #include "linguistic/misc.hxx" 57*cdf0e10cSrcweir #include "defs.hxx" 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir //using namespace utl; 60*cdf0e10cSrcweir using namespace osl; 61*cdf0e10cSrcweir using namespace rtl; 62*cdf0e10cSrcweir using namespace com::sun::star; 63*cdf0e10cSrcweir using namespace com::sun::star::lang; 64*cdf0e10cSrcweir using namespace com::sun::star::uno; 65*cdf0e10cSrcweir using namespace com::sun::star::container; 66*cdf0e10cSrcweir using namespace com::sun::star::linguistic2; 67*cdf0e10cSrcweir using namespace linguistic; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir #define SN_CONV_DICTIONARY_LIST "com.sun.star.linguistic2.ConversionDictionaryList" 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir bool operator == ( const Locale &r1, const Locale &r2 ) 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir return r1.Language == r2.Language && 77*cdf0e10cSrcweir r1.Country == r2.Country && 78*cdf0e10cSrcweir r1.Variant == r2.Variant; 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir String GetConvDicMainURL( const String &rDicName, const String &rDirectoryURL ) 84*cdf0e10cSrcweir { 85*cdf0e10cSrcweir // build URL to use for new (persistent) dictionaries 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir String aFullDicName( rDicName ); 88*cdf0e10cSrcweir aFullDicName.AppendAscii( CONV_DIC_DOT_EXT ); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir INetURLObject aURLObj; 91*cdf0e10cSrcweir aURLObj.SetSmartProtocol( INET_PROT_FILE ); 92*cdf0e10cSrcweir aURLObj.SetSmartURL( rDirectoryURL ); 93*cdf0e10cSrcweir aURLObj.Append( aFullDicName, INetURLObject::ENCODE_ALL ); 94*cdf0e10cSrcweir DBG_ASSERT(!aURLObj.HasError(), "invalid URL"); 95*cdf0e10cSrcweir if (aURLObj.HasError()) 96*cdf0e10cSrcweir return String(); 97*cdf0e10cSrcweir else 98*cdf0e10cSrcweir return aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI ); 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir class ConvDicNameContainer : 104*cdf0e10cSrcweir public cppu::WeakImplHelper1 105*cdf0e10cSrcweir < 106*cdf0e10cSrcweir ::com::sun::star::container::XNameContainer 107*cdf0e10cSrcweir > 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir uno::Sequence< uno::Reference< XConversionDictionary > > aConvDics; 110*cdf0e10cSrcweir ConvDicList &rConvDicList; 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir // disallow copy-constructor and assignment-operator for now 113*cdf0e10cSrcweir ConvDicNameContainer(const ConvDicNameContainer &); 114*cdf0e10cSrcweir ConvDicNameContainer & operator = (const ConvDicNameContainer &); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir sal_Int32 GetIndexByName_Impl( const OUString& rName ); 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir public: 119*cdf0e10cSrcweir ConvDicNameContainer( ConvDicList &rMyConvDicList ); 120*cdf0e10cSrcweir virtual ~ConvDicNameContainer(); 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir // XElementAccess 123*cdf0e10cSrcweir virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException); 124*cdf0e10cSrcweir virtual sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException); 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir // XNameAccess 127*cdf0e10cSrcweir virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 128*cdf0e10cSrcweir virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException); 129*cdf0e10cSrcweir virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir // XNameReplace 132*cdf0e10cSrcweir virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir // XNameContainer 135*cdf0e10cSrcweir virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 136*cdf0e10cSrcweir virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir // looks for conversion dictionaries with the specified extension 140*cdf0e10cSrcweir // in the directory and adds them to the container 141*cdf0e10cSrcweir void AddConvDics( const String &rSearchDirPathURL, const String &rExtension ); 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir // calls Flush for the dictionaries that support XFlushable 144*cdf0e10cSrcweir void FlushDics() const; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir sal_Int32 GetCount() const { return aConvDics.getLength(); } 147*cdf0e10cSrcweir uno::Reference< XConversionDictionary > GetByName( const OUString& rName ); 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir const uno::Reference< XConversionDictionary > GetByIndex( sal_Int32 nIdx ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir return aConvDics.getConstArray()[nIdx]; 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir }; 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir ConvDicNameContainer::ConvDicNameContainer( ConvDicList &rMyConvDicList ) : 157*cdf0e10cSrcweir rConvDicList( rMyConvDicList ) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir ConvDicNameContainer::~ConvDicNameContainer() 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir void ConvDicNameContainer::FlushDics() const 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir sal_Int32 nLen = aConvDics.getLength(); 170*cdf0e10cSrcweir const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray(); 171*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir uno::Reference< util::XFlushable > xFlush( pDic[i] , UNO_QUERY ); 174*cdf0e10cSrcweir if (xFlush.is()) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir try 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir xFlush->flush(); 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir catch(Exception &) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir DBG_ERROR( "flushing of conversion dictionary failed" ); 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir sal_Int32 ConvDicNameContainer::GetIndexByName_Impl( 190*cdf0e10cSrcweir const OUString& rName ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir sal_Int32 nRes = -1; 193*cdf0e10cSrcweir sal_Int32 nLen = aConvDics.getLength(); 194*cdf0e10cSrcweir const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray(); 195*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir if (rName == pDic[i]->getName()) 198*cdf0e10cSrcweir nRes = i; 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir return nRes; 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir uno::Reference< XConversionDictionary > ConvDicNameContainer::GetByName( 205*cdf0e10cSrcweir const OUString& rName ) 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xRes; 208*cdf0e10cSrcweir sal_Int32 nIdx = GetIndexByName_Impl( rName ); 209*cdf0e10cSrcweir if ( nIdx != -1) 210*cdf0e10cSrcweir xRes = aConvDics.getArray()[nIdx]; 211*cdf0e10cSrcweir return xRes; 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir uno::Type SAL_CALL ConvDicNameContainer::getElementType( ) 216*cdf0e10cSrcweir throw (RuntimeException) 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 219*cdf0e10cSrcweir return uno::Type( ::getCppuType( (uno::Reference< XConversionDictionary > *) 0) ); 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir sal_Bool SAL_CALL ConvDicNameContainer::hasElements( ) 224*cdf0e10cSrcweir throw (RuntimeException) 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 227*cdf0e10cSrcweir return aConvDics.getLength() > 0; 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir uno::Any SAL_CALL ConvDicNameContainer::getByName( const OUString& rName ) 232*cdf0e10cSrcweir throw (NoSuchElementException, WrappedTargetException, RuntimeException) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 235*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xRes( GetByName( rName ) ); 236*cdf0e10cSrcweir if (!xRes.is()) 237*cdf0e10cSrcweir throw NoSuchElementException(); 238*cdf0e10cSrcweir return makeAny( xRes ); 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL ConvDicNameContainer::getElementNames( ) 243*cdf0e10cSrcweir throw (RuntimeException) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir sal_Int32 nLen = aConvDics.getLength(); 248*cdf0e10cSrcweir uno::Sequence< OUString > aRes( nLen ); 249*cdf0e10cSrcweir OUString *pName = aRes.getArray(); 250*cdf0e10cSrcweir const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray(); 251*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i) 252*cdf0e10cSrcweir pName[i] = pDic[i]->getName(); 253*cdf0e10cSrcweir return aRes; 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir sal_Bool SAL_CALL ConvDicNameContainer::hasByName( const OUString& rName ) 258*cdf0e10cSrcweir throw (RuntimeException) 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 261*cdf0e10cSrcweir return GetByName( rName ).is(); 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir void SAL_CALL ConvDicNameContainer::replaceByName( 266*cdf0e10cSrcweir const OUString& rName, 267*cdf0e10cSrcweir const uno::Any& rElement ) 268*cdf0e10cSrcweir throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir sal_Int32 nRplcIdx = GetIndexByName_Impl( rName ); 273*cdf0e10cSrcweir if (nRplcIdx == -1) 274*cdf0e10cSrcweir throw NoSuchElementException(); 275*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xNew; 276*cdf0e10cSrcweir rElement >>= xNew; 277*cdf0e10cSrcweir if (!xNew.is() || xNew->getName() != rName) 278*cdf0e10cSrcweir throw IllegalArgumentException(); 279*cdf0e10cSrcweir aConvDics.getArray()[ nRplcIdx ] = xNew; 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir void SAL_CALL ConvDicNameContainer::insertByName( 284*cdf0e10cSrcweir const OUString& rName, 285*cdf0e10cSrcweir const Any& rElement ) 286*cdf0e10cSrcweir throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir if (GetByName( rName ).is()) 291*cdf0e10cSrcweir throw ElementExistException(); 292*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xNew; 293*cdf0e10cSrcweir rElement >>= xNew; 294*cdf0e10cSrcweir if (!xNew.is() || xNew->getName() != rName) 295*cdf0e10cSrcweir throw IllegalArgumentException(); 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir sal_Int32 nLen = aConvDics.getLength(); 298*cdf0e10cSrcweir aConvDics.realloc( nLen + 1 ); 299*cdf0e10cSrcweir aConvDics.getArray()[ nLen ] = xNew; 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir void SAL_CALL ConvDicNameContainer::removeByName( const OUString& rName ) 304*cdf0e10cSrcweir throw (NoSuchElementException, WrappedTargetException, RuntimeException) 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir sal_Int32 nRplcIdx = GetIndexByName_Impl( rName ); 309*cdf0e10cSrcweir if (nRplcIdx == -1) 310*cdf0e10cSrcweir throw NoSuchElementException(); 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir // physically remove dictionary 313*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xDel = aConvDics.getArray()[nRplcIdx]; 314*cdf0e10cSrcweir String aName( xDel->getName() ); 315*cdf0e10cSrcweir String aDicMainURL( GetConvDicMainURL( aName, GetDictionaryWriteablePath() ) ); 316*cdf0e10cSrcweir INetURLObject aObj( aDicMainURL ); 317*cdf0e10cSrcweir DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE, "+HangulHanjaOptionsDialog::OkHdl(): non-file URLs cannot be deleted" ); 318*cdf0e10cSrcweir if( aObj.GetProtocol() == INET_PROT_FILE ) 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir try 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), 323*cdf0e10cSrcweir uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); 324*cdf0e10cSrcweir aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir catch( ::com::sun::star::ucb::CommandAbortedException& ) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): CommandAbortedException" ); 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir catch( ... ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): Any other exception" ); 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir sal_Int32 nLen = aConvDics.getLength(); 337*cdf0e10cSrcweir uno::Reference< XConversionDictionary > *pDic = aConvDics.getArray(); 338*cdf0e10cSrcweir for (sal_Int32 i = nRplcIdx; i < nLen - 1; ++i) 339*cdf0e10cSrcweir pDic[i] = pDic[i + 1]; 340*cdf0e10cSrcweir aConvDics.realloc( nLen - 1 ); 341*cdf0e10cSrcweir } 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir void ConvDicNameContainer::AddConvDics( 345*cdf0e10cSrcweir const String &rSearchDirPathURL, 346*cdf0e10cSrcweir const String &rExtension ) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir const Sequence< OUString > aDirCnt( 349*cdf0e10cSrcweir utl::LocalFileHelper::GetFolderContents( rSearchDirPathURL, sal_False ) ); 350*cdf0e10cSrcweir const OUString *pDirCnt = aDirCnt.getConstArray(); 351*cdf0e10cSrcweir sal_Int32 nEntries = aDirCnt.getLength(); 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nEntries; ++i) 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir String aURL( pDirCnt[i] ); 356*cdf0e10cSrcweir 357*cdf0e10cSrcweir xub_StrLen nPos = aURL.SearchBackward('.'); 358*cdf0e10cSrcweir String aExt(aURL.Copy(nPos + 1)); 359*cdf0e10cSrcweir aExt.ToLowerAscii(); 360*cdf0e10cSrcweir String aSearchExt( rExtension ); 361*cdf0e10cSrcweir aSearchExt.ToLowerAscii(); 362*cdf0e10cSrcweir if(aExt != aSearchExt) 363*cdf0e10cSrcweir continue; // skip other files 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir sal_Int16 nLang; 366*cdf0e10cSrcweir sal_Int16 nConvType; 367*cdf0e10cSrcweir if (IsConvDic( aURL, nLang, nConvType )) 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir // get decoded dictionary file name 370*cdf0e10cSrcweir INetURLObject aURLObj( aURL ); 371*cdf0e10cSrcweir String aDicName = aURLObj.getBase( INetURLObject::LAST_SEGMENT, 372*cdf0e10cSrcweir true, INetURLObject::DECODE_WITH_CHARSET, 373*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ); 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir uno::Reference < XConversionDictionary > xDic; 376*cdf0e10cSrcweir if (nLang == LANGUAGE_KOREAN && 377*cdf0e10cSrcweir nConvType == ConversionDictionaryType::HANGUL_HANJA) 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir xDic = new HHConvDic( aDicName, aURL ); 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) && 382*cdf0e10cSrcweir nConvType == ConversionDictionaryType::SCHINESE_TCHINESE) 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir xDic = new ConvDic( aDicName, nLang, nConvType, sal_False, aURL ); 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir if (xDic.is()) 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir uno::Any aAny; 390*cdf0e10cSrcweir aAny <<= xDic; 391*cdf0e10cSrcweir insertByName( xDic->getName(), aAny ); 392*cdf0e10cSrcweir } 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir } 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir namespace 400*cdf0e10cSrcweir { 401*cdf0e10cSrcweir struct StaticConvDicList : public rtl::StaticWithInit< 402*cdf0e10cSrcweir uno::Reference<XInterface>, StaticConvDicList> { 403*cdf0e10cSrcweir uno::Reference<XInterface> operator () () { 404*cdf0e10cSrcweir return (cppu::OWeakObject *) new ConvDicList; 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir }; 407*cdf0e10cSrcweir } 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir void ConvDicList::MyAppExitListener::AtExit() 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir rMyDicList.FlushDics(); 413*cdf0e10cSrcweir StaticConvDicList::get().clear(); 414*cdf0e10cSrcweir } 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir ConvDicList::ConvDicList() : 417*cdf0e10cSrcweir aEvtListeners( GetLinguMutex() ) 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir pNameContainer = 0; 420*cdf0e10cSrcweir bDisposing = sal_False; 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir pExitListener = new MyAppExitListener( *this ); 423*cdf0e10cSrcweir xExitListener = pExitListener; 424*cdf0e10cSrcweir pExitListener->Activate(); 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir ConvDicList::~ConvDicList() 429*cdf0e10cSrcweir { 430*cdf0e10cSrcweir // NameContainer will deleted when the reference xNameContainer 431*cdf0e10cSrcweir // is destroyed. 432*cdf0e10cSrcweir // delete pNameContainer; 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir if (!bDisposing && pNameContainer) 435*cdf0e10cSrcweir pNameContainer->FlushDics(); 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir pExitListener->Deactivate(); 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir void ConvDicList::FlushDics() 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir // check only pointer to avoid creating the container when 444*cdf0e10cSrcweir // the dictionaries were not accessed yet 445*cdf0e10cSrcweir if (pNameContainer) 446*cdf0e10cSrcweir pNameContainer->FlushDics(); 447*cdf0e10cSrcweir } 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir ConvDicNameContainer & ConvDicList::GetNameContainer() 451*cdf0e10cSrcweir { 452*cdf0e10cSrcweir if (!pNameContainer) 453*cdf0e10cSrcweir { 454*cdf0e10cSrcweir pNameContainer = new ConvDicNameContainer( *this ); 455*cdf0e10cSrcweir pNameContainer->AddConvDics( GetDictionaryWriteablePath(), 456*cdf0e10cSrcweir A2OU( CONV_DIC_EXT ) ); 457*cdf0e10cSrcweir xNameContainer = pNameContainer; 458*cdf0e10cSrcweir 459*cdf0e10cSrcweir // access list of text conversion dictionaries to activate 460*cdf0e10cSrcweir SvtLinguOptions aOpt; 461*cdf0e10cSrcweir SvtLinguConfig().GetOptions( aOpt ); 462*cdf0e10cSrcweir sal_Int32 nLen = aOpt.aActiveConvDics.getLength(); 463*cdf0e10cSrcweir const OUString *pActiveConvDics = aOpt.aActiveConvDics.getConstArray(); 464*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xDic = 467*cdf0e10cSrcweir pNameContainer->GetByName( pActiveConvDics[i] ); 468*cdf0e10cSrcweir if (xDic.is()) 469*cdf0e10cSrcweir xDic->setActive( sal_True ); 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir // since there is no UI to active/deactivate the dictionaries 473*cdf0e10cSrcweir // for chinese text conversion they should be activated by default 474*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xS2TDic( 475*cdf0e10cSrcweir pNameContainer->GetByName( A2OU("ChineseS2T") ), UNO_QUERY ); 476*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xT2SDic( 477*cdf0e10cSrcweir pNameContainer->GetByName( A2OU("ChineseT2S") ), UNO_QUERY ); 478*cdf0e10cSrcweir if (xS2TDic.is()) 479*cdf0e10cSrcweir xS2TDic->setActive( sal_True ); 480*cdf0e10cSrcweir if (xT2SDic.is()) 481*cdf0e10cSrcweir xT2SDic->setActive( sal_True ); 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir return *pNameContainer; 485*cdf0e10cSrcweir } 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir uno::Reference< container::XNameContainer > SAL_CALL ConvDicList::getDictionaryContainer( ) throw (RuntimeException) 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 491*cdf0e10cSrcweir GetNameContainer(); 492*cdf0e10cSrcweir DBG_ASSERT( xNameContainer.is(), "missing name container" ); 493*cdf0e10cSrcweir return xNameContainer; 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir uno::Reference< XConversionDictionary > SAL_CALL ConvDicList::addNewDictionary( 498*cdf0e10cSrcweir const OUString& rName, 499*cdf0e10cSrcweir const Locale& rLocale, 500*cdf0e10cSrcweir sal_Int16 nConvDicType ) 501*cdf0e10cSrcweir throw (NoSupportException, ElementExistException, RuntimeException) 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir sal_Int16 nLang = LocaleToLanguage( rLocale ); 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir if (GetNameContainer().hasByName( rName )) 508*cdf0e10cSrcweir throw ElementExistException(); 509*cdf0e10cSrcweir 510*cdf0e10cSrcweir uno::Reference< XConversionDictionary > xRes; 511*cdf0e10cSrcweir String aDicMainURL( GetConvDicMainURL( rName, GetDictionaryWriteablePath() ) ); 512*cdf0e10cSrcweir if (nLang == LANGUAGE_KOREAN && 513*cdf0e10cSrcweir nConvDicType == ConversionDictionaryType::HANGUL_HANJA) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir xRes = new HHConvDic( rName, aDicMainURL ); 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) && 518*cdf0e10cSrcweir nConvDicType == ConversionDictionaryType::SCHINESE_TCHINESE) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir xRes = new ConvDic( rName, nLang, nConvDicType, sal_False, aDicMainURL ); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir if (!xRes.is()) 524*cdf0e10cSrcweir throw NoSupportException(); 525*cdf0e10cSrcweir else 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir xRes->setActive( sal_True ); 528*cdf0e10cSrcweir uno::Any aAny; 529*cdf0e10cSrcweir aAny <<= xRes; 530*cdf0e10cSrcweir GetNameContainer().insertByName( rName, aAny ); 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir return xRes; 533*cdf0e10cSrcweir } 534*cdf0e10cSrcweir 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL ConvDicList::queryConversions( 537*cdf0e10cSrcweir const OUString& rText, 538*cdf0e10cSrcweir sal_Int32 nStartPos, 539*cdf0e10cSrcweir sal_Int32 nLength, 540*cdf0e10cSrcweir const Locale& rLocale, 541*cdf0e10cSrcweir sal_Int16 nConversionDictionaryType, 542*cdf0e10cSrcweir ConversionDirection eDirection, 543*cdf0e10cSrcweir sal_Int32 nTextConversionOptions ) 544*cdf0e10cSrcweir throw (IllegalArgumentException, NoSupportException, RuntimeException) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir /*sal_Int16 nLang = LocaleToLanguage( rLocale );*/ 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir sal_Int32 nCount = 0; 551*cdf0e10cSrcweir uno::Sequence< OUString > aRes( 20 ); 552*cdf0e10cSrcweir OUString *pRes = aRes.getArray(); 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir sal_Bool bSupported = sal_False; 555*cdf0e10cSrcweir sal_Int32 nLen = GetNameContainer().GetCount(); 556*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i) 557*cdf0e10cSrcweir { 558*cdf0e10cSrcweir const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) ); 559*cdf0e10cSrcweir sal_Bool bMatch = xDic.is() && 560*cdf0e10cSrcweir xDic->getLocale() == rLocale && 561*cdf0e10cSrcweir xDic->getConversionType() == nConversionDictionaryType; 562*cdf0e10cSrcweir bSupported |= bMatch; 563*cdf0e10cSrcweir if (bMatch && xDic->isActive()) 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir Sequence< OUString > aNewConv( xDic->getConversions( 566*cdf0e10cSrcweir rText, nStartPos, nLength, 567*cdf0e10cSrcweir eDirection, nTextConversionOptions ) ); 568*cdf0e10cSrcweir sal_Int32 nNewLen = aNewConv.getLength(); 569*cdf0e10cSrcweir if (nNewLen > 0) 570*cdf0e10cSrcweir { 571*cdf0e10cSrcweir if (nCount + nNewLen > aRes.getLength()) 572*cdf0e10cSrcweir { 573*cdf0e10cSrcweir aRes.realloc( nCount + nNewLen + 20 ); 574*cdf0e10cSrcweir pRes = aRes.getArray(); 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir const OUString *pNewConv = aNewConv.getConstArray(); 577*cdf0e10cSrcweir for (sal_Int32 k = 0; k < nNewLen; ++k) 578*cdf0e10cSrcweir pRes[nCount++] = pNewConv[k]; 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir if (!bSupported) 584*cdf0e10cSrcweir throw NoSupportException(); 585*cdf0e10cSrcweir 586*cdf0e10cSrcweir aRes.realloc( nCount ); 587*cdf0e10cSrcweir return aRes; 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir 591*cdf0e10cSrcweir sal_Int16 SAL_CALL ConvDicList::queryMaxCharCount( 592*cdf0e10cSrcweir const Locale& rLocale, 593*cdf0e10cSrcweir sal_Int16 nConversionDictionaryType, 594*cdf0e10cSrcweir ConversionDirection eDirection ) 595*cdf0e10cSrcweir throw (RuntimeException) 596*cdf0e10cSrcweir { 597*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir sal_Int16 nRes = 0; 600*cdf0e10cSrcweir GetNameContainer(); 601*cdf0e10cSrcweir sal_Int32 nLen = GetNameContainer().GetCount(); 602*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i) 603*cdf0e10cSrcweir { 604*cdf0e10cSrcweir const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) ); 605*cdf0e10cSrcweir if (xDic.is() && 606*cdf0e10cSrcweir xDic->getLocale() == rLocale && 607*cdf0e10cSrcweir xDic->getConversionType() == nConversionDictionaryType) 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir sal_Int16 nC = xDic->getMaxCharCount( eDirection ); 610*cdf0e10cSrcweir if (nC > nRes) 611*cdf0e10cSrcweir nRes = nC; 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir } 614*cdf0e10cSrcweir return nRes; 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir void SAL_CALL ConvDicList::dispose( ) 619*cdf0e10cSrcweir throw (RuntimeException) 620*cdf0e10cSrcweir { 621*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 622*cdf0e10cSrcweir if (!bDisposing) 623*cdf0e10cSrcweir { 624*cdf0e10cSrcweir bDisposing = sal_True; 625*cdf0e10cSrcweir EventObject aEvtObj( (XConversionDictionaryList *) this ); 626*cdf0e10cSrcweir aEvtListeners.disposeAndClear( aEvtObj ); 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir FlushDics(); 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir void SAL_CALL ConvDicList::addEventListener( 634*cdf0e10cSrcweir const uno::Reference< XEventListener >& rxListener ) 635*cdf0e10cSrcweir throw (RuntimeException) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 638*cdf0e10cSrcweir if (!bDisposing && rxListener.is()) 639*cdf0e10cSrcweir aEvtListeners.addInterface( rxListener ); 640*cdf0e10cSrcweir } 641*cdf0e10cSrcweir 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir void SAL_CALL ConvDicList::removeEventListener( 644*cdf0e10cSrcweir const uno::Reference< XEventListener >& rxListener ) 645*cdf0e10cSrcweir throw (RuntimeException) 646*cdf0e10cSrcweir { 647*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 648*cdf0e10cSrcweir if (!bDisposing && rxListener.is()) 649*cdf0e10cSrcweir aEvtListeners.removeInterface( rxListener ); 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir OUString SAL_CALL ConvDicList::getImplementationName( ) 654*cdf0e10cSrcweir throw (RuntimeException) 655*cdf0e10cSrcweir { 656*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 657*cdf0e10cSrcweir return getImplementationName_Static(); 658*cdf0e10cSrcweir } 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir 661*cdf0e10cSrcweir sal_Bool SAL_CALL ConvDicList::supportsService( const OUString& rServiceName ) 662*cdf0e10cSrcweir throw (RuntimeException) 663*cdf0e10cSrcweir { 664*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 665*cdf0e10cSrcweir return rServiceName.equalsAscii( SN_CONV_DICTIONARY_LIST ); 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL ConvDicList::getSupportedServiceNames( ) 670*cdf0e10cSrcweir throw (RuntimeException) 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() ); 673*cdf0e10cSrcweir return getSupportedServiceNames_Static(); 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir uno::Sequence< OUString > ConvDicList::getSupportedServiceNames_Static() 678*cdf0e10cSrcweir throw() 679*cdf0e10cSrcweir { 680*cdf0e10cSrcweir uno::Sequence< OUString > aSNS( 1 ); 681*cdf0e10cSrcweir aSNS.getArray()[0] = A2OU( SN_CONV_DICTIONARY_LIST ); 682*cdf0e10cSrcweir return aSNS; 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir 686*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 687*cdf0e10cSrcweir 688*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL ConvDicList_CreateInstance( 689*cdf0e10cSrcweir const uno::Reference< XMultiServiceFactory > & /*rSMgr*/ ) 690*cdf0e10cSrcweir throw(Exception) 691*cdf0e10cSrcweir { 692*cdf0e10cSrcweir return StaticConvDicList::get(); 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir void * SAL_CALL ConvDicList_getFactory( 696*cdf0e10cSrcweir const sal_Char * pImplName, 697*cdf0e10cSrcweir XMultiServiceFactory * pServiceManager, void * ) 698*cdf0e10cSrcweir { 699*cdf0e10cSrcweir void * pRet = 0; 700*cdf0e10cSrcweir if ( !ConvDicList::getImplementationName_Static().compareToAscii( pImplName ) ) 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir uno::Reference< XSingleServiceFactory > xFactory = 703*cdf0e10cSrcweir cppu::createOneInstanceFactory( 704*cdf0e10cSrcweir pServiceManager, 705*cdf0e10cSrcweir ConvDicList::getImplementationName_Static(), 706*cdf0e10cSrcweir ConvDicList_CreateInstance, 707*cdf0e10cSrcweir ConvDicList::getSupportedServiceNames_Static()); 708*cdf0e10cSrcweir // acquire, because we return an interface pointer instead of a reference 709*cdf0e10cSrcweir xFactory->acquire(); 710*cdf0e10cSrcweir pRet = xFactory.get(); 711*cdf0e10cSrcweir } 712*cdf0e10cSrcweir return pRet; 713*cdf0e10cSrcweir } 714*cdf0e10cSrcweir 715*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 716*cdf0e10cSrcweir 717