blob: b2fd8f358d186fdba723cdcbcbc57aacf9d45751 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_unotools.hxx"
#include <unotools/transliterationwrapper.hxx>
#include <tools/debug.hxx>
#include <i18npool/mslangid.hxx>
#include <comphelper/componentfactory.hxx>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
#define TRANSLIT_LIBRARYNAME "i18n"
#define TRANSLIT_SERVICENAME "com.sun.star.i18n.Transliteration"
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star::uno;
using namespace ::utl;
TransliterationWrapper::TransliterationWrapper(
const Reference< XMultiServiceFactory > & xSF,
sal_uInt32 nTyp )
: xSMgr( xSF ), nType( nTyp ), nLanguage( 0 ), bFirstCall( sal_True )
{
if( xSMgr.is() )
{
try {
xTrans = Reference< XExtendedTransliteration > (
xSMgr->createInstance( ::rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
TRANSLIT_SERVICENAME))), UNO_QUERY );
}
catch ( Exception& )
{
DBG_ERRORFILE( "TransliterationWrapper: Exception caught!" );
}
}
else
{ // try to get an instance somehow
DBG_ERRORFILE( "TransliterationWrapper: no service manager, trying own" );
try
{
Reference< XInterface > xI = ::comphelper::getComponentInstance(
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME(
TRANSLIT_LIBRARYNAME ))),
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
TRANSLIT_SERVICENAME)));
if ( xI.is() )
{
Any x = xI->queryInterface(
::getCppuType((const Reference< XExtendedTransliteration>*)0) );
x >>= xTrans ;
}
}
catch ( Exception& )
{
DBG_ERRORFILE( "getComponentInstance: Exception caught!" );
}
}
DBG_ASSERT( xTrans.is(), "TransliterationWrapper: no Transliteraion available" );
}
TransliterationWrapper::~TransliterationWrapper()
{
}
String TransliterationWrapper::transliterate(
const String& rStr, sal_uInt16 nLang,
xub_StrLen nStart, xub_StrLen nLen,
Sequence <sal_Int32>* pOffset )
{
String sRet;
if( xTrans.is() )
{
try
{
loadModuleIfNeeded( nLang );
if ( pOffset )
sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset );
else
sRet = xTrans->transliterateString2String( rStr, nStart, nLen);
}
catch( Exception& )
{
DBG_ERRORFILE( "transliterate: Exception caught!" );
}
}
return sRet;
}
String TransliterationWrapper::transliterate(
const String& rStr,
xub_StrLen nStart, xub_StrLen nLen,
Sequence <sal_Int32>* pOffset ) const
{
String sRet( rStr );
if( xTrans.is() )
{
try
{
if ( pOffset )
sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset );
else
sRet = xTrans->transliterateString2String( rStr, nStart, nLen);
}
catch( Exception& )
{
DBG_ERRORFILE( "transliterate: Exception caught!" );
}
}
return sRet;
}
sal_Bool TransliterationWrapper::needLanguageForTheMode() const
{
return TransliterationModules_UPPERCASE_LOWERCASE == nType ||
TransliterationModules_LOWERCASE_UPPERCASE == nType ||
TransliterationModules_IGNORE_CASE == nType ||
(sal_uInt32) TransliterationModulesExtra::SENTENCE_CASE == (sal_uInt32) nType ||
(sal_uInt32) TransliterationModulesExtra::TITLE_CASE == (sal_uInt32) nType ||
(sal_uInt32) TransliterationModulesExtra::TOGGLE_CASE == (sal_uInt32) nType;
}
void TransliterationWrapper::setLanguageLocaleImpl( sal_uInt16 nLang )
{
nLanguage = nLang;
if( LANGUAGE_NONE == nLanguage )
nLanguage = LANGUAGE_SYSTEM;
MsLangId::convertLanguageToLocale( nLanguage, aLocale);
}
void TransliterationWrapper::loadModuleIfNeeded( sal_uInt16 nLang )
{
sal_Bool bLoad = bFirstCall;
bFirstCall = sal_False;
if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::SENTENCE_CASE )
{
if( bLoad )
loadModuleByImplName(String::CreateFromAscii("SENTENCE_CASE"), nLang);
}
else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TITLE_CASE )
{
if( bLoad )
loadModuleByImplName(String::CreateFromAscii("TITLE_CASE"), nLang);
}
else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TOGGLE_CASE )
{
if( bLoad )
loadModuleByImplName(String::CreateFromAscii("TOGGLE_CASE"), nLang);
}
else
{
if( nLanguage != nLang )
{
setLanguageLocaleImpl( nLang );
if( !bLoad )
bLoad = needLanguageForTheMode();
}
if( bLoad )
loadModuleImpl();
}
}
void TransliterationWrapper::loadModuleImpl() const
{
if ( bFirstCall )
((TransliterationWrapper*)this)->setLanguageLocaleImpl( LANGUAGE_SYSTEM );
try
{
if ( xTrans.is() )
xTrans->loadModule( (TransliterationModules)nType, aLocale );
}
catch ( Exception& e )
{
#ifdef DBG_UTIL
ByteString aMsg( "loadModuleImpl: Exception caught\n" );
aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
DBG_ERRORFILE( aMsg.GetBuffer() );
#else
(void)e;
#endif
}
bFirstCall = sal_False;
}
void TransliterationWrapper::loadModuleByImplName(
const String& rModuleName, sal_uInt16 nLang )
{
try
{
setLanguageLocaleImpl( nLang );
// Reset LanguageType, so the next call to loadModuleIfNeeded() forces
// new settings.
nLanguage = LANGUAGE_DONTKNOW;
if ( xTrans.is() )
xTrans->loadModuleByImplName( rModuleName, aLocale );
}
catch ( Exception& e )
{
#ifdef DBG_UTIL
ByteString aMsg( "loadModuleByImplName: Exception caught\n" );
aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
DBG_ERRORFILE( aMsg.GetBuffer() );
#else
(void)e;
#endif
}
bFirstCall = sal_False;
}
sal_Bool TransliterationWrapper::equals(
const String& rStr1, sal_Int32 nPos1, sal_Int32 nCount1, sal_Int32& nMatch1,
const String& rStr2, sal_Int32 nPos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) const
{
try
{
if( bFirstCall )
loadModuleImpl();
if ( xTrans.is() )
return xTrans->equals( rStr1, nPos1, nCount1, nMatch1, rStr2, nPos2, nCount2, nMatch2 );
}
catch ( Exception& e )
{
#ifdef DBG_UTIL
ByteString aMsg( "equals: Exception caught\n" );
aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
DBG_ERRORFILE( aMsg.GetBuffer() );
#else
(void)e;
#endif
}
return sal_False;
}
sal_Int32 TransliterationWrapper::compareSubstring(
const String& rStr1, sal_Int32 nOff1, sal_Int32 nLen1,
const String& rStr2, sal_Int32 nOff2, sal_Int32 nLen2 ) const
{
try
{
if( bFirstCall )
loadModuleImpl();
if ( xTrans.is() )
return xTrans->compareSubstring( rStr1, nOff1, nLen1, rStr2, nOff2, nLen2 );
}
catch ( Exception& e )
{
#ifdef DBG_UTIL
ByteString aMsg( "compareSubstring: Exception caught\n" );
aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
DBG_ERRORFILE( aMsg.GetBuffer() );
#else
(void)e;
#endif
}
return 0;
}
sal_Int32 TransliterationWrapper::compareString( const String& rStr1, const String& rStr2 ) const
{
try
{
if( bFirstCall )
loadModuleImpl();
if ( xTrans.is() )
return xTrans->compareString( rStr1, rStr2 );
}
catch ( Exception& e )
{
#ifdef DBG_UTIL
ByteString aMsg( "compareString: Exception caught\n" );
aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
DBG_ERRORFILE( aMsg.GetBuffer() );
#else
(void)e;
#endif
}
return 0;
}
// --- helpers --------------------------------------------------------
sal_Bool TransliterationWrapper::isEqual( const String& rStr1, const String& rStr2 ) const
{
sal_Int32 nMatch1, nMatch2;
sal_Bool bMatch = equals(
rStr1, 0, rStr1.Len(), nMatch1,
rStr2, 0, rStr2.Len(), nMatch2 );
return bMatch;
}
sal_Bool TransliterationWrapper::isMatch( const String& rStr1, const String& rStr2 ) const
{
sal_Int32 nMatch1, nMatch2;
equals(
rStr1, 0, rStr1.Len(), nMatch1,
rStr2, 0, rStr2.Len(), nMatch2 );
return (nMatch1 <= nMatch2) && (nMatch1 == rStr1.Len());
}