1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_i18npool.hxx" 30 31 #include <inputsequencechecker.hxx> 32 #include <com/sun/star/i18n/InputSequenceCheckMode.hpp> 33 #include <com/sun/star/i18n/UnicodeType.hpp> 34 #include <i18nutil/unicode.hxx> 35 #include <rtl/ustrbuf.hxx> 36 37 using namespace ::com::sun::star::uno; 38 using namespace ::com::sun::star::lang; 39 using namespace ::rtl; 40 41 namespace com { namespace sun { namespace star { namespace i18n { 42 43 InputSequenceCheckerImpl::InputSequenceCheckerImpl( const Reference < XMultiServiceFactory >& rxMSF ) : xMSF( rxMSF ) 44 { 45 serviceName = "com.sun.star.i18n.InputSequenceCheckerImpl"; 46 cachedItem = NULL; 47 } 48 49 InputSequenceCheckerImpl::InputSequenceCheckerImpl() 50 { 51 } 52 53 InputSequenceCheckerImpl::~InputSequenceCheckerImpl() 54 { 55 // Clear lookuptable 56 for (size_t l = 0; l < lookupTable.size(); l++) 57 delete lookupTable[l]; 58 59 lookupTable.clear(); 60 } 61 62 sal_Bool SAL_CALL 63 InputSequenceCheckerImpl::checkInputSequence(const OUString& Text, sal_Int32 nStartPos, 64 sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(RuntimeException) 65 { 66 if (inputCheckMode == InputSequenceCheckMode::PASSTHROUGH) 67 return sal_True; 68 69 sal_Char* language = getLanguageByScripType(Text[nStartPos], inputChar); 70 71 if (language) 72 return getInputSequenceChecker(language)->checkInputSequence(Text, nStartPos, inputChar, inputCheckMode); 73 else 74 return sal_True; // not a checkable languages. 75 } 76 77 sal_Int32 SAL_CALL 78 InputSequenceCheckerImpl::correctInputSequence(OUString& Text, sal_Int32 nStartPos, 79 sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(RuntimeException) 80 { 81 if (inputCheckMode != InputSequenceCheckMode::PASSTHROUGH) { 82 sal_Char* language = getLanguageByScripType(Text[nStartPos], inputChar); 83 84 if (language) 85 return getInputSequenceChecker(language)->correctInputSequence(Text, nStartPos, inputChar, inputCheckMode); 86 } 87 Text = Text.replaceAt(++nStartPos, 0, OUString(inputChar)); 88 return nStartPos; 89 } 90 91 static ScriptTypeList typeList[] = { 92 //{ UnicodeScript_kHebrew, UnicodeScript_kHebrew }, // 10, 93 //{ UnicodeScript_kArabic, UnicodeScript_kArabic }, // 11, 94 { UnicodeScript_kDevanagari,UnicodeScript_kDevanagari, UnicodeScript_kDevanagari }, // 14, 95 { UnicodeScript_kThai, UnicodeScript_kThai, UnicodeScript_kThai }, // 24, 96 97 { UnicodeScript_kScriptCount, UnicodeScript_kScriptCount, UnicodeScript_kScriptCount } // 88 98 }; 99 100 sal_Char* SAL_CALL 101 InputSequenceCheckerImpl::getLanguageByScripType(sal_Unicode cChar, sal_Unicode nChar) 102 { 103 sal_Int16 type = unicode::getUnicodeScriptType( cChar, typeList, UnicodeScript_kScriptCount ); 104 105 if (type != UnicodeScript_kScriptCount && 106 type == unicode::getUnicodeScriptType( nChar, typeList, UnicodeScript_kScriptCount )) { 107 switch(type) { 108 case UnicodeScript_kThai: return (sal_Char*)"th"; 109 //case UnicodeScript_kArabic: return (sal_Char*)"ar"; 110 //case UnicodeScript_kHebrew: return (sal_Char*)"he"; 111 case UnicodeScript_kDevanagari: return (sal_Char*)"hi"; 112 } 113 } 114 return NULL; 115 } 116 117 Reference< XExtendedInputSequenceChecker >& SAL_CALL 118 InputSequenceCheckerImpl::getInputSequenceChecker(sal_Char* rLanguage) throw (RuntimeException) 119 { 120 if (cachedItem && cachedItem->aLanguage == rLanguage) { 121 return cachedItem->xISC; 122 } 123 else if (xMSF.is()) { 124 for (size_t l = 0; l < lookupTable.size(); l++) { 125 cachedItem = lookupTable[l]; 126 if (cachedItem->aLanguage == rLanguage) 127 return cachedItem->xISC; 128 } 129 130 Reference < uno::XInterface > xI = xMSF->createInstance( 131 OUString::createFromAscii("com.sun.star.i18n.InputSequenceChecker_") + 132 OUString::createFromAscii(rLanguage)); 133 134 if ( xI.is() ) { 135 Reference< XExtendedInputSequenceChecker > xISC; 136 xI->queryInterface( getCppuType((const Reference< XExtendedInputSequenceChecker>*)0) ) >>= xISC; 137 if (xISC.is()) { 138 lookupTable.push_back(cachedItem = new lookupTableItem(rLanguage, xISC)); 139 return cachedItem->xISC; 140 } 141 } 142 } 143 throw RuntimeException(); 144 } 145 146 OUString SAL_CALL 147 InputSequenceCheckerImpl::getImplementationName(void) throw( RuntimeException ) 148 { 149 return OUString::createFromAscii(serviceName); 150 } 151 152 sal_Bool SAL_CALL 153 InputSequenceCheckerImpl::supportsService(const OUString& rServiceName) throw( RuntimeException ) 154 { 155 return !rServiceName.compareToAscii(serviceName); 156 } 157 158 Sequence< OUString > SAL_CALL 159 InputSequenceCheckerImpl::getSupportedServiceNames(void) throw( RuntimeException ) 160 { 161 Sequence< OUString > aRet(1); 162 aRet[0] = OUString::createFromAscii(serviceName); 163 return aRet; 164 } 165 166 } } } } 167