1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_i18npool.hxx" 26 27 #include <inputsequencechecker.hxx> 28 #include <com/sun/star/i18n/InputSequenceCheckMode.hpp> 29 #include <com/sun/star/i18n/UnicodeType.hpp> 30 #include <i18nutil/unicode.hxx> 31 #include <rtl/ustrbuf.hxx> 32 33 using namespace ::com::sun::star::uno; 34 using namespace ::com::sun::star::lang; 35 using namespace ::rtl; 36 37 namespace com { namespace sun { namespace star { namespace i18n { 38 39 InputSequenceCheckerImpl::InputSequenceCheckerImpl( const Reference < XMultiServiceFactory >& rxMSF ) : xMSF( rxMSF ) 40 { 41 serviceName = "com.sun.star.i18n.InputSequenceCheckerImpl"; 42 cachedItem = NULL; 43 } 44 45 InputSequenceCheckerImpl::InputSequenceCheckerImpl() 46 { 47 } 48 49 InputSequenceCheckerImpl::~InputSequenceCheckerImpl() 50 { 51 // Clear lookuptable 52 for (size_t l = 0; l < lookupTable.size(); l++) 53 delete lookupTable[l]; 54 55 lookupTable.clear(); 56 } 57 58 sal_Bool SAL_CALL 59 InputSequenceCheckerImpl::checkInputSequence(const OUString& Text, sal_Int32 nStartPos, 60 sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(RuntimeException) 61 { 62 if (inputCheckMode == InputSequenceCheckMode::PASSTHROUGH) 63 return sal_True; 64 65 sal_Char* language = getLanguageByScripType(Text[nStartPos], inputChar); 66 67 if (language) 68 return getInputSequenceChecker(language)->checkInputSequence(Text, nStartPos, inputChar, inputCheckMode); 69 else 70 return sal_True; // not a checkable languages. 71 } 72 73 sal_Int32 SAL_CALL 74 InputSequenceCheckerImpl::correctInputSequence(OUString& Text, sal_Int32 nStartPos, 75 sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(RuntimeException) 76 { 77 if (inputCheckMode != InputSequenceCheckMode::PASSTHROUGH) { 78 sal_Char* language = getLanguageByScripType(Text[nStartPos], inputChar); 79 80 if (language) 81 return getInputSequenceChecker(language)->correctInputSequence(Text, nStartPos, inputChar, inputCheckMode); 82 } 83 Text = Text.replaceAt(++nStartPos, 0, OUString(inputChar)); 84 return nStartPos; 85 } 86 87 static ScriptTypeList typeList[] = { 88 //{ UnicodeScript_kHebrew, UnicodeScript_kHebrew }, // 10, 89 //{ UnicodeScript_kArabic, UnicodeScript_kArabic }, // 11, 90 { UnicodeScript_kDevanagari,UnicodeScript_kDevanagari, UnicodeScript_kDevanagari }, // 14, 91 { UnicodeScript_kThai, UnicodeScript_kThai, UnicodeScript_kThai }, // 24, 92 93 { UnicodeScript_kScriptCount, UnicodeScript_kScriptCount, UnicodeScript_kScriptCount } // 88 94 }; 95 96 sal_Char* SAL_CALL 97 InputSequenceCheckerImpl::getLanguageByScripType(sal_Unicode cChar, sal_Unicode nChar) 98 { 99 sal_Int16 type = unicode::getUnicodeScriptType( cChar, typeList, UnicodeScript_kScriptCount ); 100 101 if (type != UnicodeScript_kScriptCount && 102 type == unicode::getUnicodeScriptType( nChar, typeList, UnicodeScript_kScriptCount )) { 103 switch(type) { 104 case UnicodeScript_kThai: return (sal_Char*)"th"; 105 //case UnicodeScript_kArabic: return (sal_Char*)"ar"; 106 //case UnicodeScript_kHebrew: return (sal_Char*)"he"; 107 case UnicodeScript_kDevanagari: return (sal_Char*)"hi"; 108 } 109 } 110 return NULL; 111 } 112 113 Reference< XExtendedInputSequenceChecker >& SAL_CALL 114 InputSequenceCheckerImpl::getInputSequenceChecker(sal_Char* rLanguage) throw (RuntimeException) 115 { 116 if (cachedItem && cachedItem->aLanguage == rLanguage) { 117 return cachedItem->xISC; 118 } 119 else if (xMSF.is()) { 120 for (size_t l = 0; l < lookupTable.size(); l++) { 121 cachedItem = lookupTable[l]; 122 if (cachedItem->aLanguage == rLanguage) 123 return cachedItem->xISC; 124 } 125 126 Reference < uno::XInterface > xI = xMSF->createInstance( 127 OUString::createFromAscii("com.sun.star.i18n.InputSequenceChecker_") + 128 OUString::createFromAscii(rLanguage)); 129 130 if ( xI.is() ) { 131 Reference< XExtendedInputSequenceChecker > xISC; 132 xI->queryInterface( getCppuType((const Reference< XExtendedInputSequenceChecker>*)0) ) >>= xISC; 133 if (xISC.is()) { 134 lookupTable.push_back(cachedItem = new lookupTableItem(rLanguage, xISC)); 135 return cachedItem->xISC; 136 } 137 } 138 } 139 throw RuntimeException(); 140 } 141 142 OUString SAL_CALL 143 InputSequenceCheckerImpl::getImplementationName(void) throw( RuntimeException ) 144 { 145 return OUString::createFromAscii(serviceName); 146 } 147 148 sal_Bool SAL_CALL 149 InputSequenceCheckerImpl::supportsService(const OUString& rServiceName) throw( RuntimeException ) 150 { 151 return !rServiceName.compareToAscii(serviceName); 152 } 153 154 Sequence< OUString > SAL_CALL 155 InputSequenceCheckerImpl::getSupportedServiceNames(void) throw( RuntimeException ) 156 { 157 Sequence< OUString > aRet(1); 158 aRet[0] = OUString::createFromAscii(serviceName); 159 return aRet; 160 } 161 162 } } } } 163