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_i18npool.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <inputsequencechecker.hxx> 32*cdf0e10cSrcweir #include <com/sun/star/i18n/InputSequenceCheckMode.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/i18n/UnicodeType.hpp> 34*cdf0e10cSrcweir #include <i18nutil/unicode.hxx> 35*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 38*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 39*cdf0e10cSrcweir using namespace ::rtl; 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir namespace com { namespace sun { namespace star { namespace i18n { 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir InputSequenceCheckerImpl::InputSequenceCheckerImpl( const Reference < XMultiServiceFactory >& rxMSF ) : xMSF( rxMSF ) 44*cdf0e10cSrcweir { 45*cdf0e10cSrcweir serviceName = "com.sun.star.i18n.InputSequenceCheckerImpl"; 46*cdf0e10cSrcweir cachedItem = NULL; 47*cdf0e10cSrcweir } 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir InputSequenceCheckerImpl::InputSequenceCheckerImpl() 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir } 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir InputSequenceCheckerImpl::~InputSequenceCheckerImpl() 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir // Clear lookuptable 56*cdf0e10cSrcweir for (size_t l = 0; l < lookupTable.size(); l++) 57*cdf0e10cSrcweir delete lookupTable[l]; 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir lookupTable.clear(); 60*cdf0e10cSrcweir } 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir sal_Bool SAL_CALL 63*cdf0e10cSrcweir InputSequenceCheckerImpl::checkInputSequence(const OUString& Text, sal_Int32 nStartPos, 64*cdf0e10cSrcweir sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(RuntimeException) 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir if (inputCheckMode == InputSequenceCheckMode::PASSTHROUGH) 67*cdf0e10cSrcweir return sal_True; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir sal_Char* language = getLanguageByScripType(Text[nStartPos], inputChar); 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir if (language) 72*cdf0e10cSrcweir return getInputSequenceChecker(language)->checkInputSequence(Text, nStartPos, inputChar, inputCheckMode); 73*cdf0e10cSrcweir else 74*cdf0e10cSrcweir return sal_True; // not a checkable languages. 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir sal_Int32 SAL_CALL 78*cdf0e10cSrcweir InputSequenceCheckerImpl::correctInputSequence(OUString& Text, sal_Int32 nStartPos, 79*cdf0e10cSrcweir sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(RuntimeException) 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir if (inputCheckMode != InputSequenceCheckMode::PASSTHROUGH) { 82*cdf0e10cSrcweir sal_Char* language = getLanguageByScripType(Text[nStartPos], inputChar); 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir if (language) 85*cdf0e10cSrcweir return getInputSequenceChecker(language)->correctInputSequence(Text, nStartPos, inputChar, inputCheckMode); 86*cdf0e10cSrcweir } 87*cdf0e10cSrcweir Text = Text.replaceAt(++nStartPos, 0, OUString(inputChar)); 88*cdf0e10cSrcweir return nStartPos; 89*cdf0e10cSrcweir } 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir static ScriptTypeList typeList[] = { 92*cdf0e10cSrcweir //{ UnicodeScript_kHebrew, UnicodeScript_kHebrew }, // 10, 93*cdf0e10cSrcweir //{ UnicodeScript_kArabic, UnicodeScript_kArabic }, // 11, 94*cdf0e10cSrcweir { UnicodeScript_kDevanagari,UnicodeScript_kDevanagari, UnicodeScript_kDevanagari }, // 14, 95*cdf0e10cSrcweir { UnicodeScript_kThai, UnicodeScript_kThai, UnicodeScript_kThai }, // 24, 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir { UnicodeScript_kScriptCount, UnicodeScript_kScriptCount, UnicodeScript_kScriptCount } // 88 98*cdf0e10cSrcweir }; 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir sal_Char* SAL_CALL 101*cdf0e10cSrcweir InputSequenceCheckerImpl::getLanguageByScripType(sal_Unicode cChar, sal_Unicode nChar) 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir sal_Int16 type = unicode::getUnicodeScriptType( cChar, typeList, UnicodeScript_kScriptCount ); 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir if (type != UnicodeScript_kScriptCount && 106*cdf0e10cSrcweir type == unicode::getUnicodeScriptType( nChar, typeList, UnicodeScript_kScriptCount )) { 107*cdf0e10cSrcweir switch(type) { 108*cdf0e10cSrcweir case UnicodeScript_kThai: return (sal_Char*)"th"; 109*cdf0e10cSrcweir //case UnicodeScript_kArabic: return (sal_Char*)"ar"; 110*cdf0e10cSrcweir //case UnicodeScript_kHebrew: return (sal_Char*)"he"; 111*cdf0e10cSrcweir case UnicodeScript_kDevanagari: return (sal_Char*)"hi"; 112*cdf0e10cSrcweir } 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir return NULL; 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir Reference< XExtendedInputSequenceChecker >& SAL_CALL 118*cdf0e10cSrcweir InputSequenceCheckerImpl::getInputSequenceChecker(sal_Char* rLanguage) throw (RuntimeException) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir if (cachedItem && cachedItem->aLanguage == rLanguage) { 121*cdf0e10cSrcweir return cachedItem->xISC; 122*cdf0e10cSrcweir } 123*cdf0e10cSrcweir else if (xMSF.is()) { 124*cdf0e10cSrcweir for (size_t l = 0; l < lookupTable.size(); l++) { 125*cdf0e10cSrcweir cachedItem = lookupTable[l]; 126*cdf0e10cSrcweir if (cachedItem->aLanguage == rLanguage) 127*cdf0e10cSrcweir return cachedItem->xISC; 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir Reference < uno::XInterface > xI = xMSF->createInstance( 131*cdf0e10cSrcweir OUString::createFromAscii("com.sun.star.i18n.InputSequenceChecker_") + 132*cdf0e10cSrcweir OUString::createFromAscii(rLanguage)); 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir if ( xI.is() ) { 135*cdf0e10cSrcweir Reference< XExtendedInputSequenceChecker > xISC; 136*cdf0e10cSrcweir xI->queryInterface( getCppuType((const Reference< XExtendedInputSequenceChecker>*)0) ) >>= xISC; 137*cdf0e10cSrcweir if (xISC.is()) { 138*cdf0e10cSrcweir lookupTable.push_back(cachedItem = new lookupTableItem(rLanguage, xISC)); 139*cdf0e10cSrcweir return cachedItem->xISC; 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir throw RuntimeException(); 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir OUString SAL_CALL 147*cdf0e10cSrcweir InputSequenceCheckerImpl::getImplementationName(void) throw( RuntimeException ) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir return OUString::createFromAscii(serviceName); 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir sal_Bool SAL_CALL 153*cdf0e10cSrcweir InputSequenceCheckerImpl::supportsService(const OUString& rServiceName) throw( RuntimeException ) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir return !rServiceName.compareToAscii(serviceName); 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir Sequence< OUString > SAL_CALL 159*cdf0e10cSrcweir InputSequenceCheckerImpl::getSupportedServiceNames(void) throw( RuntimeException ) 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir Sequence< OUString > aRet(1); 162*cdf0e10cSrcweir aRet[0] = OUString::createFromAscii(serviceName); 163*cdf0e10cSrcweir return aRet; 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir } } } } 167