xref: /aoo41x/main/sc/source/core/data/documen6.cxx (revision cdf0e10c)
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