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
GetBreakIterator()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
HasStringWeakCharacters(const String & rString)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
GetStringScriptType(const String & rString)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
GetCellScriptType(ScBaseCell * pCell,sal_uLong nNumberFormat)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
GetScriptType(SCCOL nCol,SCROW nRow,SCTAB nTab,ScBaseCell * pCell)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