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_sc.hxx" 26 27 28 29 #include "scitems.hxx" 30 #include <editeng/scripttypeitem.hxx> 31 32 #include <com/sun/star/i18n/XBreakIterator.hpp> 33 #include <com/sun/star/i18n/ScriptType.hpp> 34 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 35 36 #include "document.hxx" 37 #include "cell.hxx" 38 #include "cellform.hxx" 39 #include "patattr.hxx" 40 #include "scrdata.hxx" 41 #include "poolhelp.hxx" 42 43 using namespace com::sun::star; 44 45 #define SC_BREAKITER_SERVICE "com.sun.star.i18n.BreakIterator" 46 47 // 48 // this file is compiled with exceptions enabled 49 // put functions here that need exceptions! 50 // 51 52 // ----------------------------------------------------------------------- 53 54 const uno::Reference< i18n::XBreakIterator >& ScDocument::GetBreakIterator() 55 { 56 if ( !pScriptTypeData ) 57 pScriptTypeData = new ScScriptTypeData; 58 if ( !pScriptTypeData->xBreakIter.is() ) 59 { 60 uno::Reference< uno::XInterface > xInterface = xServiceManager->createInstance( 61 ::rtl::OUString::createFromAscii( SC_BREAKITER_SERVICE ) ); 62 pScriptTypeData->xBreakIter = uno::Reference< i18n::XBreakIterator >( xInterface, uno::UNO_QUERY ); 63 DBG_ASSERT( pScriptTypeData->xBreakIter.is(), "can't get BreakIterator" ); 64 } 65 return pScriptTypeData->xBreakIter; 66 } 67 68 sal_Bool ScDocument::HasStringWeakCharacters( const String& rString ) 69 { 70 if (rString.Len()) 71 { 72 uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator(); 73 if ( xBreakIter.is() ) 74 { 75 rtl::OUString aText = rString; 76 sal_Int32 nLen = aText.getLength(); 77 78 sal_Int32 nPos = 0; 79 do 80 { 81 sal_Int16 nType = xBreakIter->getScriptType( aText, nPos ); 82 if ( nType == i18n::ScriptType::WEAK ) 83 return sal_True; // found 84 85 nPos = xBreakIter->endOfScript( aText, nPos, nType ); 86 } 87 while ( nPos >= 0 && nPos < nLen ); 88 } 89 } 90 91 return sal_False; // none found 92 } 93 94 sal_uInt8 ScDocument::GetStringScriptType( const String& rString ) 95 { 96 97 sal_uInt8 nRet = 0; 98 if (rString.Len()) 99 { 100 uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator(); 101 if ( xBreakIter.is() ) 102 { 103 rtl::OUString aText = rString; 104 sal_Int32 nLen = aText.getLength(); 105 106 sal_Int32 nPos = 0; 107 do 108 { 109 sal_Int16 nType = xBreakIter->getScriptType( aText, nPos ); 110 switch ( nType ) 111 { 112 case i18n::ScriptType::LATIN: 113 nRet |= SCRIPTTYPE_LATIN; 114 break; 115 case i18n::ScriptType::ASIAN: 116 nRet |= SCRIPTTYPE_ASIAN; 117 break; 118 case i18n::ScriptType::COMPLEX: 119 nRet |= SCRIPTTYPE_COMPLEX; 120 break; 121 // WEAK is ignored 122 } 123 nPos = xBreakIter->endOfScript( aText, nPos, nType ); 124 } 125 while ( nPos >= 0 && nPos < nLen ); 126 } 127 } 128 return nRet; 129 } 130 131 sal_uInt8 ScDocument::GetCellScriptType( ScBaseCell* pCell, sal_uLong nNumberFormat ) 132 { 133 if ( !pCell ) 134 return 0; // empty 135 136 sal_uInt8 nStored = pCell->GetScriptType(); 137 if ( nStored != SC_SCRIPTTYPE_UNKNOWN ) // stored value valid? 138 return nStored; // use stored value 139 140 String aStr; 141 Color* pColor; 142 ScCellFormat::GetString( pCell, nNumberFormat, aStr, &pColor, *xPoolHelper->GetFormTable() ); 143 144 sal_uInt8 nRet = GetStringScriptType( aStr ); 145 146 pCell->SetScriptType( nRet ); // store for later calls 147 148 return nRet; 149 } 150 151 sal_uInt8 ScDocument::GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell ) 152 { 153 // if cell is not passed, take from document 154 155 if (!pCell) 156 { 157 pCell = GetCell( ScAddress( nCol, nRow, nTab ) ); 158 if ( !pCell ) 159 return 0; // empty 160 } 161 162 // if script type is set, don't have to get number formats 163 164 sal_uInt8 nStored = pCell->GetScriptType(); 165 if ( nStored != SC_SCRIPTTYPE_UNKNOWN ) // stored value valid? 166 return nStored; // use stored value 167 168 // include number formats from conditional formatting 169 170 const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab ); 171 if (!pPattern) return 0; 172 const SfxItemSet* pCondSet = NULL; 173 if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() ) 174 pCondSet = GetCondResult( nCol, nRow, nTab ); 175 176 sal_uLong nFormat = pPattern->GetNumberFormat( xPoolHelper->GetFormTable(), pCondSet ); 177 return GetCellScriptType( pCell, nFormat ); 178 } 179 180 181