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