diff options
Diffstat (limited to 'linguistic/source/convdiclist.cxx')
-rw-r--r-- | linguistic/source/convdiclist.cxx | 705 |
1 files changed, 705 insertions, 0 deletions
diff --git a/linguistic/source/convdiclist.cxx b/linguistic/source/convdiclist.cxx new file mode 100644 index 000000000000..b240d13e03a6 --- /dev/null +++ b/linguistic/source/convdiclist.cxx @@ -0,0 +1,705 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_linguistic.hxx" + +#include <tools/fsys.hxx> +#include <tools/stream.hxx> +#include <tools/urlobj.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/useroptions.hxx> +#include <unotools/lingucfg.hxx> +#include <rtl/instance.hxx> +#include <cppuhelper/factory.hxx> // helper for factories +#include <unotools/localfilehelper.hxx> +#include <com/sun/star/linguistic2/XConversionDictionaryList.hpp> +#include <com/sun/star/linguistic2/XConversionDictionary.hpp> +#include <com/sun/star/linguistic2/ConversionDictionaryType.hpp> +#include <com/sun/star/util/XFlushable.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/container/XNameContainer.hpp> + +#include <ucbhelper/content.hxx> + +#include "convdiclist.hxx" +#include "convdic.hxx" +#include "hhconvdic.hxx" +#include "linguistic/misc.hxx" +#include "defs.hxx" + +using namespace osl; +using namespace com::sun::star; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace com::sun::star::container; +using namespace com::sun::star::linguistic2; +using namespace linguistic; + +using ::rtl::OUString; + +#define SN_CONV_DICTIONARY_LIST "com.sun.star.linguistic2.ConversionDictionaryList" + + + +bool operator == ( const Locale &r1, const Locale &r2 ) +{ + return r1.Language == r2.Language && + r1.Country == r2.Country && + r1.Variant == r2.Variant; +} + + +String GetConvDicMainURL( const String &rDicName, const String &rDirectoryURL ) +{ + // build URL to use for new (persistent) dictionaries + + String aFullDicName( rDicName ); + aFullDicName.AppendAscii( CONV_DIC_DOT_EXT ); + + INetURLObject aURLObj; + aURLObj.SetSmartProtocol( INET_PROT_FILE ); + aURLObj.SetSmartURL( rDirectoryURL ); + aURLObj.Append( aFullDicName, INetURLObject::ENCODE_ALL ); + DBG_ASSERT(!aURLObj.HasError(), "invalid URL"); + if (aURLObj.HasError()) + return String(); + else + return aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI ); +} + + +class ConvDicNameContainer : + public cppu::WeakImplHelper1 + < + ::com::sun::star::container::XNameContainer + > +{ + uno::Sequence< uno::Reference< XConversionDictionary > > aConvDics; + ConvDicList &rConvDicList; + + // disallow copy-constructor and assignment-operator for now + ConvDicNameContainer(const ConvDicNameContainer &); + ConvDicNameContainer & operator = (const ConvDicNameContainer &); + + sal_Int32 GetIndexByName_Impl( const OUString& rName ); + +public: + ConvDicNameContainer( ConvDicList &rMyConvDicList ); + virtual ~ConvDicNameContainer(); + + // XElementAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException); + + // XNameAccess + 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); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + + // XNameReplace + 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); + + // XNameContainer + 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); + 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); + + + // looks for conversion dictionaries with the specified extension + // in the directory and adds them to the container + void AddConvDics( const String &rSearchDirPathURL, const String &rExtension ); + + // calls Flush for the dictionaries that support XFlushable + void FlushDics() const; + + sal_Int32 GetCount() const { return aConvDics.getLength(); } + uno::Reference< XConversionDictionary > GetByName( const OUString& rName ); + + const uno::Reference< XConversionDictionary > GetByIndex( sal_Int32 nIdx ) + { + return aConvDics.getConstArray()[nIdx]; + } +}; + + +ConvDicNameContainer::ConvDicNameContainer( ConvDicList &rMyConvDicList ) : + rConvDicList( rMyConvDicList ) +{ +} + + +ConvDicNameContainer::~ConvDicNameContainer() +{ +} + + +void ConvDicNameContainer::FlushDics() const +{ + sal_Int32 nLen = aConvDics.getLength(); + const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + uno::Reference< util::XFlushable > xFlush( pDic[i] , UNO_QUERY ); + if (xFlush.is()) + { + try + { + xFlush->flush(); + } + catch(Exception &) + { + OSL_FAIL( "flushing of conversion dictionary failed" ); + } + } + } +} + + +sal_Int32 ConvDicNameContainer::GetIndexByName_Impl( + const OUString& rName ) +{ + sal_Int32 nRes = -1; + sal_Int32 nLen = aConvDics.getLength(); + const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray(); + for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i) + { + if (rName == pDic[i]->getName()) + nRes = i; + } + return nRes; +} + + +uno::Reference< XConversionDictionary > ConvDicNameContainer::GetByName( + const OUString& rName ) +{ + uno::Reference< XConversionDictionary > xRes; + sal_Int32 nIdx = GetIndexByName_Impl( rName ); + if ( nIdx != -1) + xRes = aConvDics.getArray()[nIdx]; + return xRes; +} + + +uno::Type SAL_CALL ConvDicNameContainer::getElementType( ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return uno::Type( ::getCppuType( (uno::Reference< XConversionDictionary > *) 0) ); +} + + +sal_Bool SAL_CALL ConvDicNameContainer::hasElements( ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return aConvDics.getLength() > 0; +} + + +uno::Any SAL_CALL ConvDicNameContainer::getByName( const OUString& rName ) + throw (NoSuchElementException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + uno::Reference< XConversionDictionary > xRes( GetByName( rName ) ); + if (!xRes.is()) + throw NoSuchElementException(); + return makeAny( xRes ); +} + + +uno::Sequence< OUString > SAL_CALL ConvDicNameContainer::getElementNames( ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Int32 nLen = aConvDics.getLength(); + uno::Sequence< OUString > aRes( nLen ); + OUString *pName = aRes.getArray(); + const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + pName[i] = pDic[i]->getName(); + return aRes; +} + + +sal_Bool SAL_CALL ConvDicNameContainer::hasByName( const OUString& rName ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return GetByName( rName ).is(); +} + + +void SAL_CALL ConvDicNameContainer::replaceByName( + const OUString& rName, + const uno::Any& rElement ) + throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Int32 nRplcIdx = GetIndexByName_Impl( rName ); + if (nRplcIdx == -1) + throw NoSuchElementException(); + uno::Reference< XConversionDictionary > xNew; + rElement >>= xNew; + if (!xNew.is() || xNew->getName() != rName) + throw IllegalArgumentException(); + aConvDics.getArray()[ nRplcIdx ] = xNew; +} + + +void SAL_CALL ConvDicNameContainer::insertByName( + const OUString& rName, + const Any& rElement ) + throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + if (GetByName( rName ).is()) + throw ElementExistException(); + uno::Reference< XConversionDictionary > xNew; + rElement >>= xNew; + if (!xNew.is() || xNew->getName() != rName) + throw IllegalArgumentException(); + + sal_Int32 nLen = aConvDics.getLength(); + aConvDics.realloc( nLen + 1 ); + aConvDics.getArray()[ nLen ] = xNew; +} + + +void SAL_CALL ConvDicNameContainer::removeByName( const OUString& rName ) + throw (NoSuchElementException, WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Int32 nRplcIdx = GetIndexByName_Impl( rName ); + if (nRplcIdx == -1) + throw NoSuchElementException(); + + // physically remove dictionary + uno::Reference< XConversionDictionary > xDel = aConvDics.getArray()[nRplcIdx]; + String aName( xDel->getName() ); + String aDicMainURL( GetConvDicMainURL( aName, GetDictionaryWriteablePath() ) ); + INetURLObject aObj( aDicMainURL ); + DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE, "+HangulHanjaOptionsDialog::OkHdl(): non-file URLs cannot be deleted" ); + if( aObj.GetProtocol() == INET_PROT_FILE ) + { + try + { + ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), + uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + aCnt.executeCommand( OUString(RTL_CONSTASCII_USTRINGPARAM("delete")), makeAny( sal_Bool( sal_True ) ) ); + } + catch( ::com::sun::star::ucb::CommandAbortedException& ) + { + DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): CommandAbortedException" ); + } + catch( ... ) + { + DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): Any other exception" ); + } + } + + sal_Int32 nLen = aConvDics.getLength(); + uno::Reference< XConversionDictionary > *pDic = aConvDics.getArray(); + for (sal_Int32 i = nRplcIdx; i < nLen - 1; ++i) + pDic[i] = pDic[i + 1]; + aConvDics.realloc( nLen - 1 ); +} + + +void ConvDicNameContainer::AddConvDics( + const String &rSearchDirPathURL, + const String &rExtension ) +{ + const Sequence< OUString > aDirCnt( + utl::LocalFileHelper::GetFolderContents( rSearchDirPathURL, sal_False ) ); + const OUString *pDirCnt = aDirCnt.getConstArray(); + sal_Int32 nEntries = aDirCnt.getLength(); + + for (sal_Int32 i = 0; i < nEntries; ++i) + { + String aURL( pDirCnt[i] ); + + xub_StrLen nPos = aURL.SearchBackward('.'); + String aExt(aURL.Copy(nPos + 1)); + aExt.ToLowerAscii(); + String aSearchExt( rExtension ); + aSearchExt.ToLowerAscii(); + if(aExt != aSearchExt) + continue; // skip other files + + sal_Int16 nLang; + sal_Int16 nConvType; + if (IsConvDic( aURL, nLang, nConvType )) + { + // get decoded dictionary file name + INetURLObject aURLObj( aURL ); + String aDicName = aURLObj.getBase( INetURLObject::LAST_SEGMENT, + true, INetURLObject::DECODE_WITH_CHARSET, + RTL_TEXTENCODING_UTF8 ); + + uno::Reference < XConversionDictionary > xDic; + if (nLang == LANGUAGE_KOREAN && + nConvType == ConversionDictionaryType::HANGUL_HANJA) + { + xDic = new HHConvDic( aDicName, aURL ); + } + else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) && + nConvType == ConversionDictionaryType::SCHINESE_TCHINESE) + { + xDic = new ConvDic( aDicName, nLang, nConvType, sal_False, aURL ); + } + + if (xDic.is()) + { + uno::Any aAny; + aAny <<= xDic; + insertByName( xDic->getName(), aAny ); + } + } + } +} + + +namespace +{ + struct StaticConvDicList : public rtl::StaticWithInit< + uno::Reference<XInterface>, StaticConvDicList> { + uno::Reference<XInterface> operator () () { + return (cppu::OWeakObject *) new ConvDicList; + } + }; +} + + +void ConvDicList::MyAppExitListener::AtExit() +{ + rMyDicList.FlushDics(); + StaticConvDicList::get().clear(); +} + +ConvDicList::ConvDicList() : + aEvtListeners( GetLinguMutex() ) +{ + pNameContainer = 0; + bDisposing = sal_False; + + pExitListener = new MyAppExitListener( *this ); + xExitListener = pExitListener; + pExitListener->Activate(); +} + + +ConvDicList::~ConvDicList() +{ + + if (!bDisposing && pNameContainer) + pNameContainer->FlushDics(); + + pExitListener->Deactivate(); +} + + +void ConvDicList::FlushDics() +{ + // check only pointer to avoid creating the container when + // the dictionaries were not accessed yet + if (pNameContainer) + pNameContainer->FlushDics(); +} + + +ConvDicNameContainer & ConvDicList::GetNameContainer() +{ + if (!pNameContainer) + { + pNameContainer = new ConvDicNameContainer( *this ); + pNameContainer->AddConvDics( GetDictionaryWriteablePath(), + A2OU( CONV_DIC_EXT ) ); + xNameContainer = pNameContainer; + + // access list of text conversion dictionaries to activate + SvtLinguOptions aOpt; + SvtLinguConfig().GetOptions( aOpt ); + sal_Int32 nLen = aOpt.aActiveConvDics.getLength(); + const OUString *pActiveConvDics = aOpt.aActiveConvDics.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + uno::Reference< XConversionDictionary > xDic = + pNameContainer->GetByName( pActiveConvDics[i] ); + if (xDic.is()) + xDic->setActive( sal_True ); + } + + // since there is no UI to active/deactivate the dictionaries + // for chinese text conversion they should be activated by default + uno::Reference< XConversionDictionary > xS2TDic( + pNameContainer->GetByName( A2OU("ChineseS2T") ), UNO_QUERY ); + uno::Reference< XConversionDictionary > xT2SDic( + pNameContainer->GetByName( A2OU("ChineseT2S") ), UNO_QUERY ); + if (xS2TDic.is()) + xS2TDic->setActive( sal_True ); + if (xT2SDic.is()) + xT2SDic->setActive( sal_True ); + + } + return *pNameContainer; +} + + +uno::Reference< container::XNameContainer > SAL_CALL ConvDicList::getDictionaryContainer( ) throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + GetNameContainer(); + DBG_ASSERT( xNameContainer.is(), "missing name container" ); + return xNameContainer; +} + + +uno::Reference< XConversionDictionary > SAL_CALL ConvDicList::addNewDictionary( + const OUString& rName, + const Locale& rLocale, + sal_Int16 nConvDicType ) + throw (NoSupportException, ElementExistException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Int16 nLang = LocaleToLanguage( rLocale ); + + if (GetNameContainer().hasByName( rName )) + throw ElementExistException(); + + uno::Reference< XConversionDictionary > xRes; + String aDicMainURL( GetConvDicMainURL( rName, GetDictionaryWriteablePath() ) ); + if (nLang == LANGUAGE_KOREAN && + nConvDicType == ConversionDictionaryType::HANGUL_HANJA) + { + xRes = new HHConvDic( rName, aDicMainURL ); + } + else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) && + nConvDicType == ConversionDictionaryType::SCHINESE_TCHINESE) + { + xRes = new ConvDic( rName, nLang, nConvDicType, sal_False, aDicMainURL ); + } + + if (!xRes.is()) + throw NoSupportException(); + else + { + xRes->setActive( sal_True ); + uno::Any aAny; + aAny <<= xRes; + GetNameContainer().insertByName( rName, aAny ); + } + return xRes; +} + + +uno::Sequence< OUString > SAL_CALL ConvDicList::queryConversions( + const OUString& rText, + sal_Int32 nStartPos, + sal_Int32 nLength, + const Locale& rLocale, + sal_Int16 nConversionDictionaryType, + ConversionDirection eDirection, + sal_Int32 nTextConversionOptions ) + throw (IllegalArgumentException, NoSupportException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Int32 nCount = 0; + uno::Sequence< OUString > aRes( 20 ); + OUString *pRes = aRes.getArray(); + + sal_Bool bSupported = sal_False; + sal_Int32 nLen = GetNameContainer().GetCount(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) ); + sal_Bool bMatch = xDic.is() && + xDic->getLocale() == rLocale && + xDic->getConversionType() == nConversionDictionaryType; + bSupported |= bMatch; + if (bMatch && xDic->isActive()) + { + Sequence< OUString > aNewConv( xDic->getConversions( + rText, nStartPos, nLength, + eDirection, nTextConversionOptions ) ); + sal_Int32 nNewLen = aNewConv.getLength(); + if (nNewLen > 0) + { + if (nCount + nNewLen > aRes.getLength()) + { + aRes.realloc( nCount + nNewLen + 20 ); + pRes = aRes.getArray(); + } + const OUString *pNewConv = aNewConv.getConstArray(); + for (sal_Int32 k = 0; k < nNewLen; ++k) + pRes[nCount++] = pNewConv[k]; + } + } + } + + if (!bSupported) + throw NoSupportException(); + + aRes.realloc( nCount ); + return aRes; +} + + +sal_Int16 SAL_CALL ConvDicList::queryMaxCharCount( + const Locale& rLocale, + sal_Int16 nConversionDictionaryType, + ConversionDirection eDirection ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + sal_Int16 nRes = 0; + GetNameContainer(); + sal_Int32 nLen = GetNameContainer().GetCount(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) ); + if (xDic.is() && + xDic->getLocale() == rLocale && + xDic->getConversionType() == nConversionDictionaryType) + { + sal_Int16 nC = xDic->getMaxCharCount( eDirection ); + if (nC > nRes) + nRes = nC; + } + } + return nRes; +} + + +void SAL_CALL ConvDicList::dispose( ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + if (!bDisposing) + { + bDisposing = sal_True; + EventObject aEvtObj( (XConversionDictionaryList *) this ); + aEvtListeners.disposeAndClear( aEvtObj ); + + FlushDics(); + } +} + + +void SAL_CALL ConvDicList::addEventListener( + const uno::Reference< XEventListener >& rxListener ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + if (!bDisposing && rxListener.is()) + aEvtListeners.addInterface( rxListener ); +} + + +void SAL_CALL ConvDicList::removeEventListener( + const uno::Reference< XEventListener >& rxListener ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + if (!bDisposing && rxListener.is()) + aEvtListeners.removeInterface( rxListener ); +} + + +OUString SAL_CALL ConvDicList::getImplementationName( ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getImplementationName_Static(); +} + + +sal_Bool SAL_CALL ConvDicList::supportsService( const OUString& rServiceName ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return rServiceName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(SN_CONV_DICTIONARY_LIST)); +} + + +uno::Sequence< OUString > SAL_CALL ConvDicList::getSupportedServiceNames( ) + throw (RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + return getSupportedServiceNames_Static(); +} + + +uno::Sequence< OUString > ConvDicList::getSupportedServiceNames_Static() + throw() +{ + uno::Sequence< OUString > aSNS( 1 ); + aSNS.getArray()[0] = A2OU( SN_CONV_DICTIONARY_LIST ); + return aSNS; +} + + + +uno::Reference< uno::XInterface > SAL_CALL ConvDicList_CreateInstance( + const uno::Reference< XMultiServiceFactory > & /*rSMgr*/ ) + throw(Exception) +{ + return StaticConvDicList::get(); +} + +void * SAL_CALL ConvDicList_getFactory( + const sal_Char * pImplName, + XMultiServiceFactory * pServiceManager, void * ) +{ + void * pRet = 0; + if ( !ConvDicList::getImplementationName_Static().compareToAscii( pImplName ) ) + { + uno::Reference< XSingleServiceFactory > xFactory = + cppu::createOneInstanceFactory( + pServiceManager, + ConvDicList::getImplementationName_Static(), + ConvDicList_CreateInstance, + ConvDicList::getSupportedServiceNames_Static()); + // acquire, because we return an interface pointer instead of a reference + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |