Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <algorithm>
31 : : #include <math.h>
32 : : #include <sal/mathconf.h>
33 : : #include <unotools/fontcvt.hxx>
34 : : #include <sfx2/objsh.hxx>
35 : : #include <sal/macros.h>
36 : : #include <editeng/editstat.hxx>
37 : : #include <filter/msfilter/msvbahelper.hxx>
38 : : #include "xestream.hxx"
39 : : #include "document.hxx"
40 : : #include "docuno.hxx"
41 : : #include "editutil.hxx"
42 : : #include "formula/errorcodes.hxx"
43 : : #include "globstr.hrc"
44 : : #include "xlstyle.hxx"
45 : : #include "xlname.hxx"
46 : : #include "xistream.hxx"
47 : : #include "xiroot.hxx"
48 : : #include "xltools.hxx"
49 : :
50 : : using ::rtl::OUString;
51 : :
52 : : // GUID import/export =========================================================
53 : :
54 : 24 : XclGuid::XclGuid()
55 : : {
56 [ + - ]: 24 : ::std::fill( mpnData, STATIC_TABLE_END( mpnData ), 0 );
57 : 24 : }
58 : :
59 : 24 : XclGuid::XclGuid(
60 : : sal_uInt32 nData1, sal_uInt16 nData2, sal_uInt16 nData3,
61 : : sal_uInt8 nData41, sal_uInt8 nData42, sal_uInt8 nData43, sal_uInt8 nData44,
62 : : sal_uInt8 nData45, sal_uInt8 nData46, sal_uInt8 nData47, sal_uInt8 nData48 )
63 : : {
64 : : // convert to little endian -> makes streaming easy
65 : 24 : UInt32ToSVBT32( nData1, mpnData );
66 : 24 : ShortToSVBT16( nData2, mpnData + 4 );
67 : 24 : ShortToSVBT16( nData3, mpnData + 6 );
68 : 24 : mpnData[ 8 ] = nData41;
69 : 24 : mpnData[ 9 ] = nData42;
70 : 24 : mpnData[ 10 ] = nData43;
71 : 24 : mpnData[ 11 ] = nData44;
72 : 24 : mpnData[ 12 ] = nData45;
73 : 24 : mpnData[ 13 ] = nData46;
74 : 24 : mpnData[ 14 ] = nData47;
75 : 24 : mpnData[ 15 ] = nData48;
76 : 24 : }
77 : :
78 : 48 : bool operator==( const XclGuid& rCmp1, const XclGuid& rCmp2 )
79 : : {
80 : 48 : return ::std::equal( rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ), rCmp2.mpnData );
81 : : }
82 : :
83 : 0 : bool operator<( const XclGuid& rCmp1, const XclGuid& rCmp2 )
84 : : {
85 : : return ::std::lexicographical_compare(
86 : : rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ),
87 : 0 : rCmp2.mpnData, STATIC_TABLE_END( rCmp2.mpnData ) );
88 : : }
89 : :
90 : 48 : XclImpStream& operator>>( XclImpStream& rStrm, XclGuid& rGuid )
91 : : {
92 : 48 : rStrm.Read( rGuid.mpnData, 16 ); // mpnData always in little endian
93 : 48 : return rStrm;
94 : : }
95 : :
96 : 0 : XclExpStream& operator<<( XclExpStream& rStrm, const XclGuid& rGuid )
97 : : {
98 : 0 : rStrm.Write( rGuid.mpnData, 16 ); // mpnData already in little endian
99 : 0 : return rStrm;
100 : : }
101 : :
102 : : // Excel Tools ================================================================
103 : :
104 : : // GUID's ---------------------------------------------------------------------
105 : :
106 : 8 : const XclGuid XclTools::maGuidStdLink(
107 : : 0x79EAC9D0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
108 : :
109 : 8 : const XclGuid XclTools::maGuidUrlMoniker(
110 : : 0x79EAC9E0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
111 : :
112 : 8 : const XclGuid XclTools::maGuidFileMoniker(
113 : : 0x00000303, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
114 : :
115 : : // numeric conversion ---------------------------------------------------------
116 : :
117 : 3602 : double XclTools::GetDoubleFromRK( sal_Int32 nRKValue )
118 : : {
119 : : union
120 : : {
121 : : double fVal;
122 : : sal_math_Double smD;
123 : : };
124 : 3602 : fVal = 0.0;
125 : :
126 [ + + ]: 3602 : if( ::get_flag( nRKValue, EXC_RK_INTFLAG ) )
127 : : {
128 : 1521 : sal_Int32 nTemp = nRKValue >> 2;
129 : 1521 : ::set_flag< sal_Int32 >( nTemp, 0xE0000000, nRKValue < 0 );
130 : 1521 : fVal = nTemp;
131 : : }
132 : : else
133 : : {
134 : 2081 : smD.w32_parts.msw = nRKValue & EXC_RK_VALUEMASK;
135 : : }
136 : :
137 [ + + ]: 3602 : if( ::get_flag( nRKValue, EXC_RK_100FLAG ) )
138 : 1323 : fVal /= 100.0;
139 : :
140 : 3602 : return fVal;
141 : : }
142 : :
143 : 0 : bool XclTools::GetRKFromDouble( sal_Int32& rnRKValue, double fValue )
144 : : {
145 : : double fFrac, fInt;
146 : :
147 : : // integer
148 : 0 : fFrac = modf( fValue, &fInt );
149 [ # # ][ # # ]: 0 : if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) ) // 2^29
[ # # ]
150 : : {
151 : 0 : rnRKValue = static_cast< sal_Int32 >( fInt );
152 : 0 : rnRKValue <<= 2;
153 : 0 : rnRKValue |= EXC_RK_INT;
154 : 0 : return true;
155 : : }
156 : :
157 : : // integer/100
158 : 0 : fFrac = modf( fValue * 100.0, &fInt );
159 [ # # ][ # # ]: 0 : if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) )
[ # # ]
160 : : {
161 : 0 : rnRKValue = static_cast< sal_Int32 >( fInt );
162 : 0 : rnRKValue <<= 2;
163 : 0 : rnRKValue |= EXC_RK_INT100;
164 : 0 : return true;
165 : : }
166 : :
167 : : // double
168 : 0 : return false;
169 : : }
170 : :
171 : 201 : sal_Int32 XclTools::GetScRotation( sal_uInt16 nXclRot, sal_Int32 nRotForStacked )
172 : : {
173 [ - + ]: 201 : if( nXclRot == EXC_ROT_STACKED )
174 : 0 : return nRotForStacked;
175 : : OSL_ENSURE( nXclRot <= 180, "XclTools::GetScRotation - illegal rotation angle" );
176 [ + - ][ - + ]: 201 : return static_cast< sal_Int32 >( (nXclRot <= 180) ? (100 * ((nXclRot > 90) ? (450 - nXclRot) : nXclRot)) : 0 );
177 : : }
178 : :
179 : 0 : sal_uInt8 XclTools::GetXclRotation( sal_Int32 nScRot )
180 : : {
181 : 0 : sal_Int32 nXclRot = nScRot / 100;
182 [ # # ][ # # ]: 0 : if( (0 <= nXclRot) && (nXclRot <= 90) )
183 : 0 : return static_cast< sal_uInt8 >( nXclRot );
184 [ # # ]: 0 : if( nXclRot < 180 )
185 : 0 : return static_cast< sal_uInt8 >( 270 - nXclRot );
186 [ # # ]: 0 : if( nXclRot < 270 )
187 : 0 : return static_cast< sal_uInt8 >( nXclRot - 180 );
188 [ # # ]: 0 : if( nXclRot < 360 )
189 : 0 : return static_cast< sal_uInt8 >( 450 - nXclRot );
190 : 0 : return 0;
191 : : }
192 : :
193 : 0 : sal_uInt8 XclTools::GetXclRotFromOrient( sal_uInt8 nXclOrient )
194 : : {
195 [ # # # # : 0 : switch( nXclOrient )
# ]
196 : : {
197 : 0 : case EXC_ORIENT_NONE: return EXC_ROT_NONE;
198 : 0 : case EXC_ORIENT_STACKED: return EXC_ROT_STACKED;
199 : 0 : case EXC_ORIENT_90CCW: return EXC_ROT_90CCW;
200 : 0 : case EXC_ORIENT_90CW: return EXC_ROT_90CW;
201 : : default: OSL_FAIL( "XclTools::GetXclRotFromOrient - unknown text orientation" );
202 : : }
203 : 0 : return EXC_ROT_NONE;
204 : : }
205 : :
206 : 0 : sal_uInt8 XclTools::GetXclOrientFromRot( sal_uInt16 nXclRot )
207 : : {
208 [ # # ]: 0 : if( nXclRot == EXC_ROT_STACKED )
209 : 0 : return EXC_ORIENT_STACKED;
210 : : OSL_ENSURE( nXclRot <= 180, "XclTools::GetXclOrientFromRot - unknown text rotation" );
211 [ # # ][ # # ]: 0 : if( (45 < nXclRot) && (nXclRot <= 90) )
212 : 0 : return EXC_ORIENT_90CCW;
213 [ # # ][ # # ]: 0 : if( (135 < nXclRot) && (nXclRot <= 180) )
214 : 0 : return EXC_ORIENT_90CW;
215 : 0 : return EXC_ORIENT_NONE;
216 : : }
217 : :
218 : 0 : sal_uInt8 XclTools::GetXclErrorCode( sal_uInt16 nScError )
219 : : {
220 : : using namespace ScErrorCodes;
221 [ # # # # : 0 : switch( nScError )
# # # # #
# # # # #
# # # ]
222 : : {
223 : 0 : case errIllegalArgument: return EXC_ERR_VALUE;
224 : 0 : case errIllegalFPOperation: return EXC_ERR_NUM; // maybe DIV/0 or NUM...
225 : 0 : case errDivisionByZero: return EXC_ERR_DIV0;
226 : 0 : case errIllegalParameter: return EXC_ERR_VALUE;
227 : 0 : case errPairExpected: return EXC_ERR_VALUE;
228 : 0 : case errOperatorExpected: return EXC_ERR_VALUE;
229 : 0 : case errVariableExpected: return EXC_ERR_VALUE;
230 : 0 : case errParameterExpected: return EXC_ERR_VALUE;
231 : 0 : case errNoValue: return EXC_ERR_VALUE;
232 : 0 : case errCircularReference: return EXC_ERR_VALUE;
233 : 0 : case errNoCode: return EXC_ERR_NULL;
234 : 0 : case errNoRef: return EXC_ERR_REF;
235 : 0 : case errNoName: return EXC_ERR_NAME;
236 : 0 : case errNoAddin: return EXC_ERR_NAME;
237 : 0 : case errNoMacro: return EXC_ERR_NAME;
238 : 0 : case NOTAVAILABLE: return EXC_ERR_NA;
239 : : }
240 : 0 : return EXC_ERR_NA;
241 : : }
242 : :
243 : 0 : sal_uInt16 XclTools::GetScErrorCode( sal_uInt8 nXclError )
244 : : {
245 : : using namespace ScErrorCodes;
246 [ # # # # : 0 : switch( nXclError )
# # # # ]
247 : : {
248 : 0 : case EXC_ERR_NULL: return errNoCode;
249 : 0 : case EXC_ERR_DIV0: return errDivisionByZero;
250 : 0 : case EXC_ERR_VALUE: return errNoValue;
251 : 0 : case EXC_ERR_REF: return errNoRef;
252 : 0 : case EXC_ERR_NAME: return errNoName;
253 : 0 : case EXC_ERR_NUM: return errIllegalFPOperation;
254 : 0 : case EXC_ERR_NA: return NOTAVAILABLE;
255 : : default: OSL_FAIL( "XclTools::GetScErrorCode - unknown error code" );
256 : : }
257 : 0 : return NOTAVAILABLE;
258 : : }
259 : :
260 : 0 : double XclTools::ErrorToDouble( sal_uInt8 nXclError )
261 : : {
262 : : union
263 : : {
264 : : double fVal;
265 : : sal_math_Double smD;
266 : : };
267 : 0 : ::rtl::math::setNan( &fVal );
268 : 0 : smD.nan_parts.fraction_lo = GetScErrorCode( nXclError );
269 : 0 : return fVal;
270 : : }
271 : :
272 : 0 : XclBoolError XclTools::ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sal_uInt8 nValue )
273 : : {
274 : : XclBoolError eType;
275 [ # # ]: 0 : if( bErrOrBool )
276 : : {
277 : : // error value
278 [ # # # # : 0 : switch( nValue )
# # # # ]
279 : : {
280 : 0 : case EXC_ERR_NULL: eType = xlErrNull; break;
281 : 0 : case EXC_ERR_DIV0: eType = xlErrDiv0; break;
282 : 0 : case EXC_ERR_VALUE: eType = xlErrValue; break;
283 : 0 : case EXC_ERR_REF: eType = xlErrRef; break;
284 : 0 : case EXC_ERR_NAME: eType = xlErrName; break;
285 : 0 : case EXC_ERR_NUM: eType = xlErrNum; break;
286 : 0 : case EXC_ERR_NA: eType = xlErrNA; break;
287 : 0 : default: eType = xlErrUnknown;
288 : : }
289 : 0 : rfDblValue = 0.0;
290 : : }
291 : : else
292 : : {
293 : : // Boolean value
294 [ # # ]: 0 : eType = nValue ? xlErrTrue : xlErrFalse;
295 [ # # ]: 0 : rfDblValue = nValue ? 1.0 : 0.0;
296 : : }
297 : 0 : return eType;
298 : : }
299 : :
300 : 3025 : sal_uInt16 XclTools::GetTwipsFromInch( double fInches )
301 : : {
302 : : return static_cast< sal_uInt16 >(
303 [ + - ][ + - ]: 3025 : ::std::min( ::std::max( (fInches * EXC_TWIPS_PER_INCH + 0.5), 0.0 ), 65535.0 ) );
304 : : }
305 : :
306 : 1375 : sal_uInt16 XclTools::GetTwipsFromHmm( sal_Int32 nHmm )
307 : : {
308 : 1375 : return GetTwipsFromInch( static_cast< double >( nHmm ) / 1000.0 / CM_PER_INCH );
309 : : }
310 : :
311 : 1468 : double XclTools::GetInchFromTwips( sal_Int32 nTwips )
312 : : {
313 : 1468 : return static_cast< double >( nTwips ) / EXC_TWIPS_PER_INCH;
314 : : }
315 : :
316 : 1375 : double XclTools::GetInchFromHmm( sal_Int32 nHmm )
317 : : {
318 : 1375 : return GetInchFromTwips( GetTwipsFromHmm( nHmm ) );
319 : : }
320 : :
321 : 3 : sal_Int32 XclTools::GetHmmFromInch( double fInches )
322 : : {
323 : 3 : return static_cast< sal_Int32 >( fInches * CM_PER_INCH * 1000 );
324 : : }
325 : :
326 : 3 : sal_Int32 XclTools::GetHmmFromTwips( sal_Int32 nTwips )
327 : : {
328 : 3 : return GetHmmFromInch( GetInchFromTwips( nTwips ) );
329 : : }
330 : :
331 : 453 : sal_uInt16 XclTools::GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth )
332 : : {
333 : 453 : double fScWidth = static_cast< double >( nXclWidth ) / 256.0 * nScCharWidth + 0.5;
334 : 453 : return limit_cast< sal_uInt16 >( fScWidth );
335 : : }
336 : :
337 : 0 : sal_uInt16 XclTools::GetXclColumnWidth( sal_uInt16 nScWidth, long nScCharWidth )
338 : : {
339 : 0 : double fXclWidth = static_cast< double >( nScWidth ) * 256.0 / nScCharWidth + 0.5;
340 : 0 : return limit_cast< sal_uInt16 >( fXclWidth );
341 : : }
342 : :
343 : 162 : double XclTools::GetXclDefColWidthCorrection( long nXclDefFontHeight )
344 : : {
345 [ + - ]: 162 : return 40960.0 / ::std::max( nXclDefFontHeight - 15L, 60L ) + 50.0;
346 : : }
347 : :
348 : : // formatting -----------------------------------------------------------------
349 : :
350 : 298 : Color XclTools::GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt16 nXclPattern )
351 : : {
352 : : // 0x00 == 0% transparence (full rPattColor)
353 : : // 0x80 == 100% transparence (full rBackColor)
354 : : static const sal_uInt8 pnRatioTable[] =
355 : : {
356 : : 0x80, 0x00, 0x40, 0x20, 0x60, 0x40, 0x40, 0x40, // 00 - 07
357 : : 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15
358 : : 0x50, 0x70, 0x78 // 16 - 18
359 : : };
360 : : return (nXclPattern < SAL_N_ELEMENTS( pnRatioTable )) ?
361 [ + - ]: 298 : ScfTools::GetMixedColor( rPattColor, rBackColor, pnRatioTable[ nXclPattern ] ) : rPattColor;
362 : : }
363 : :
364 : : // text encoding --------------------------------------------------------------
365 : :
366 : : namespace {
367 : :
368 : : const struct XclCodePageEntry
369 : : {
370 : : sal_uInt16 mnCodePage;
371 : : rtl_TextEncoding meTextEnc;
372 : : }
373 : : pCodePageTable[] =
374 : : {
375 : : { 437, RTL_TEXTENCODING_IBM_437 }, // OEM US
376 : : // { 720, RTL_TEXTENCODING_IBM_720 }, // OEM Arabic
377 : : { 737, RTL_TEXTENCODING_IBM_737 }, // OEM Greek
378 : : { 775, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic
379 : : { 850, RTL_TEXTENCODING_IBM_850 }, // OEM Latin I
380 : : { 852, RTL_TEXTENCODING_IBM_852 }, // OEM Latin II (Central European)
381 : : { 855, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic
382 : : { 857, RTL_TEXTENCODING_IBM_857 }, // OEM Turkish
383 : : // { 858, RTL_TEXTENCODING_IBM_858 }, // OEM Multilingual Latin I with Euro
384 : : { 860, RTL_TEXTENCODING_IBM_860 }, // OEM Portugese
385 : : { 861, RTL_TEXTENCODING_IBM_861 }, // OEM Icelandic
386 : : { 862, RTL_TEXTENCODING_IBM_862 }, // OEM Hebrew
387 : : { 863, RTL_TEXTENCODING_IBM_863 }, // OEM Canadian (French)
388 : : { 864, RTL_TEXTENCODING_IBM_864 }, // OEM Arabic
389 : : { 865, RTL_TEXTENCODING_IBM_865 }, // OEM Nordic
390 : : { 866, RTL_TEXTENCODING_IBM_866 }, // OEM Cyrillic (Russian)
391 : : { 869, RTL_TEXTENCODING_IBM_869 }, // OEM Greek (Modern)
392 : : { 874, RTL_TEXTENCODING_MS_874 }, // MS Windows Thai
393 : : { 932, RTL_TEXTENCODING_MS_932 }, // MS Windows Japanese Shift-JIS
394 : : { 936, RTL_TEXTENCODING_MS_936 }, // MS Windows Chinese Simplified GBK
395 : : { 949, RTL_TEXTENCODING_MS_949 }, // MS Windows Korean (Wansung)
396 : : { 950, RTL_TEXTENCODING_MS_950 }, // MS Windows Chinese Traditional BIG5
397 : : { 1200, RTL_TEXTENCODING_DONTKNOW }, // Unicode (BIFF8) - return *_DONTKNOW to preserve old code page
398 : : { 1250, RTL_TEXTENCODING_MS_1250 }, // MS Windows Latin II (Central European)
399 : : { 1251, RTL_TEXTENCODING_MS_1251 }, // MS Windows Cyrillic
400 : : { 1252, RTL_TEXTENCODING_MS_1252 }, // MS Windows Latin I (BIFF4-BIFF8)
401 : : { 1253, RTL_TEXTENCODING_MS_1253 }, // MS Windows Greek
402 : : { 1254, RTL_TEXTENCODING_MS_1254 }, // MS Windows Turkish
403 : : { 1255, RTL_TEXTENCODING_MS_1255 }, // MS Windows Hebrew
404 : : { 1256, RTL_TEXTENCODING_MS_1256 }, // MS Windows Arabic
405 : : { 1257, RTL_TEXTENCODING_MS_1257 }, // MS Windows Baltic
406 : : { 1258, RTL_TEXTENCODING_MS_1258 }, // MS Windows Vietnamese
407 : : { 1361, RTL_TEXTENCODING_MS_1361 }, // MS Windows Korean (Johab)
408 : : { 10000, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
409 : : { 32768, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
410 : : { 32769, RTL_TEXTENCODING_MS_1252 } // MS Windows Latin I (BIFF2-BIFF3)
411 : : };
412 : : const XclCodePageEntry* const pCodePageTableEnd = STATIC_TABLE_END( pCodePageTable );
413 : :
414 : : struct XclCodePageEntry_CPPred
415 : : {
416 : 49 : inline explicit XclCodePageEntry_CPPred( sal_uInt16 nCodePage ) : mnCodePage( nCodePage ) {}
417 : 1038 : inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.mnCodePage == mnCodePage; }
418 : : sal_uInt16 mnCodePage;
419 : : };
420 : :
421 : : struct XclCodePageEntry_TEPred
422 : : {
423 : 0 : inline explicit XclCodePageEntry_TEPred( rtl_TextEncoding eTextEnc ) : meTextEnc( eTextEnc ) {}
424 : 0 : inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.meTextEnc == meTextEnc; }
425 : : rtl_TextEncoding meTextEnc;
426 : : };
427 : :
428 : : } // namespace
429 : :
430 : 49 : rtl_TextEncoding XclTools::GetTextEncoding( sal_uInt16 nCodePage )
431 : : {
432 [ + - ]: 49 : const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_CPPred( nCodePage ) );
433 [ - + ]: 49 : if( pEntry == pCodePageTableEnd )
434 : : {
435 : : OSL_TRACE( "XclTools::GetTextEncoding - unknown code page: 0x%04hX (%d)", nCodePage, nCodePage );
436 : 0 : return RTL_TEXTENCODING_DONTKNOW;
437 : : }
438 : 49 : return pEntry->meTextEnc;
439 : : }
440 : :
441 : 0 : sal_uInt16 XclTools::GetXclCodePage( rtl_TextEncoding eTextEnc )
442 : : {
443 [ # # ]: 0 : if( eTextEnc == RTL_TEXTENCODING_UNICODE )
444 : 0 : return 1200; // for BIFF8
445 : :
446 [ # # ]: 0 : const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_TEPred( eTextEnc ) );
447 [ # # ]: 0 : if( pEntry == pCodePageTableEnd )
448 : : {
449 : : OSL_TRACE( "XclTools::GetXclCodePage - unsupported text encoding: %d", eTextEnc );
450 : 0 : return 1252;
451 : : }
452 : 0 : return pEntry->mnCodePage;
453 : : }
454 : :
455 : : // font names -----------------------------------------------------------------
456 : :
457 : 0 : OUString XclTools::GetXclFontName( const OUString& rFontName )
458 : : {
459 : : // substitute with MS fonts
460 [ # # ][ # # ]: 0 : OUString aNewName = GetSubsFontName(rFontName, SUBSFONT_ONLYONE | SUBSFONT_MS);
[ # # ][ # # ]
[ # # ]
461 [ # # ]: 0 : return aNewName.isEmpty() ? rFontName : aNewName;
462 : : }
463 : :
464 : : // built-in defined names -----------------------------------------------------
465 : :
466 : 8 : const OUString XclTools::maDefNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
467 : :
468 : 8 : const OUString XclTools::maDefNamePrefixXml ( RTL_CONSTASCII_USTRINGPARAM( "_xlnm." ) );
469 : :
470 : : static const sal_Char* const ppcDefNames[] =
471 : : {
472 : : "Consolidate_Area",
473 : : "Auto_Open",
474 : : "Auto_Close",
475 : : "Extract",
476 : : "Database",
477 : : "Criteria",
478 : : "Print_Area",
479 : : "Print_Titles",
480 : : "Recorder",
481 : : "Data_Form",
482 : : "Auto_Activate",
483 : : "Auto_Deactivate",
484 : : "Sheet_Title",
485 : : "_FilterDatabase"
486 : : };
487 : :
488 : 18 : OUString XclTools::GetXclBuiltInDefName( sal_Unicode cBuiltIn )
489 : : {
490 : : OSL_ENSURE( SAL_N_ELEMENTS( ppcDefNames ) == EXC_BUILTIN_UNKNOWN,
491 : : "XclTools::GetXclBuiltInDefName - built-in defined name list modified" );
492 : :
493 [ + - ]: 18 : if( cBuiltIn < SAL_N_ELEMENTS( ppcDefNames ) )
494 : 18 : return rtl::OUString::createFromAscii(ppcDefNames[cBuiltIn]);
495 : : else
496 : 18 : return rtl::OUString::valueOf(static_cast<sal_Int32>(cBuiltIn));
497 : : }
498 : :
499 : 18 : OUString XclTools::GetBuiltInDefName( sal_Unicode cBuiltIn )
500 : : {
501 [ + - ]: 18 : rtl::OUStringBuffer aBuf(maDefNamePrefix);
502 [ + - ][ + - ]: 18 : aBuf.append(GetXclBuiltInDefName(cBuiltIn));
503 [ + - ]: 18 : return aBuf.makeStringAndClear();
504 : : }
505 : :
506 : 0 : OUString XclTools::GetBuiltInDefNameXml( sal_Unicode cBuiltIn )
507 : : {
508 [ # # ]: 0 : rtl::OUStringBuffer aBuf(maDefNamePrefixXml);
509 [ # # ][ # # ]: 0 : aBuf.append(GetXclBuiltInDefName(cBuiltIn));
510 [ # # ]: 0 : return aBuf.makeStringAndClear();
511 : : }
512 : :
513 : 0 : sal_Unicode XclTools::GetBuiltInDefNameIndex( const OUString& rDefName )
514 : : {
515 : 0 : sal_Int32 nPrefixLen = maDefNamePrefix.getLength();
516 [ # # ][ # # ]: 0 : if( String(rDefName).EqualsIgnoreCaseAscii( maDefNamePrefix, 0, nPrefixLen ) )
[ # # ][ # # ]
517 : : {
518 [ # # ]: 0 : for( sal_Unicode cBuiltIn = 0; cBuiltIn < EXC_BUILTIN_UNKNOWN; ++cBuiltIn )
519 : : {
520 [ # # ]: 0 : OUString aBuiltInName(GetXclBuiltInDefName(cBuiltIn));
521 : 0 : sal_Int32 nBuiltInLen = aBuiltInName.getLength();
522 [ # # ][ # # ]: 0 : if( String(rDefName).EqualsIgnoreCaseAscii( aBuiltInName, nPrefixLen, nBuiltInLen ) )
[ # # ][ # # ]
[ # # ][ # # ]
523 : : {
524 : : // name can be followed by underline or space character
525 : 0 : xub_StrLen nNextCharPos = nPrefixLen + nBuiltInLen;
526 [ # # ]: 0 : sal_Unicode cNextChar = (rDefName.getLength() > nNextCharPos) ? rDefName.getStr()[nNextCharPos] : '\0';
527 [ # # ][ # # ]: 0 : if( (cNextChar == '\0') || (cNextChar == ' ') || (cNextChar == '_') )
[ # # ]
528 : 0 : return cBuiltIn;
529 : : }
530 [ # # ]: 0 : }
531 : : }
532 : 0 : return EXC_BUILTIN_UNKNOWN;
533 : : }
534 : :
535 : : // built-in style names -------------------------------------------------------
536 : :
537 : 8 : const OUString XclTools::maStyleNamePrefix1( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
538 : 8 : const OUString XclTools::maStyleNamePrefix2( RTL_CONSTASCII_USTRINGPARAM( "Excel Built-in " ) );
539 : :
540 : : static const sal_Char* const ppcStyleNames[] =
541 : : {
542 : : "", // "Normal" not used directly, but localized "Default"
543 : : "RowLevel_", // outline level will be appended
544 : : "ColumnLevel_", // outline level will be appended
545 : : "Comma",
546 : : "Currency",
547 : : "Percent",
548 : : "Comma_0",
549 : : "Currency_0",
550 : : "Hyperlink",
551 : : "Followed_Hyperlink"
552 : : };
553 : :
554 : 670 : OUString XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId, const OUString& rName, sal_uInt8 nLevel )
555 : : {
556 : 670 : OUString aStyleName;
557 : :
558 [ + + ]: 670 : if( nStyleId == EXC_STYLE_NORMAL ) // "Normal" becomes "Default" style
559 : : {
560 [ + - ][ + - ]: 49 : aStyleName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
561 : : }
562 : : else
563 : : {
564 [ + - ]: 621 : rtl::OUStringBuffer aBuf(maStyleNamePrefix1);
565 [ + + ]: 621 : if( nStyleId < SAL_N_ELEMENTS( ppcStyleNames ) )
566 [ + - ]: 252 : aBuf.appendAscii(ppcStyleNames[nStyleId]);
567 [ + - ]: 369 : else if (!rName.isEmpty())
568 [ + - ]: 369 : aBuf.append(rName);
569 : : else
570 [ # # ]: 0 : aBuf.append(static_cast<sal_Int32>(nStyleId));
571 : :
572 [ + - ][ - + ]: 621 : if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
573 [ # # ]: 0 : aBuf.append(static_cast<sal_Int32>(nLevel+1));
574 : :
575 [ + - ]: 621 : aStyleName = aBuf.makeStringAndClear();
576 : : }
577 : :
578 : 670 : return aStyleName;
579 : : }
580 : :
581 : 0 : bool XclTools::IsBuiltInStyleName( const OUString& rStyleName, sal_uInt8* pnStyleId, sal_Int32* pnNextChar )
582 : : {
583 : : // "Default" becomes "Normal"
584 [ # # ]: 0 : if (rStyleName.equals(ScGlobal::GetRscString(STR_STYLENAME_STANDARD)))
585 : : {
586 [ # # ]: 0 : if( pnStyleId ) *pnStyleId = EXC_STYLE_NORMAL;
587 [ # # ]: 0 : if( pnNextChar ) *pnNextChar = rStyleName.getLength();
588 : 0 : return true;
589 : : }
590 : :
591 : : // try the other built-in styles
592 : 0 : sal_uInt8 nFoundId = 0;
593 : 0 : sal_Int32 nNextChar = 0;
594 : :
595 : 0 : sal_Int32 nPrefixLen = 0;
596 [ # # ][ # # ]: 0 : if( String(rStyleName).EqualsIgnoreCaseAscii( maStyleNamePrefix1, 0, maStyleNamePrefix1.getLength() ) )
[ # # ][ # # ]
597 : 0 : nPrefixLen = maStyleNamePrefix1.getLength();
598 [ # # ][ # # ]: 0 : else if( String(rStyleName).EqualsIgnoreCaseAscii( maStyleNamePrefix2, 0, maStyleNamePrefix2.getLength() ) )
[ # # ][ # # ]
599 : 0 : nPrefixLen = maStyleNamePrefix2.getLength();
600 [ # # ]: 0 : if( nPrefixLen > 0 )
601 : : {
602 [ # # ]: 0 : for( sal_uInt8 nId = 0; nId < SAL_N_ELEMENTS( ppcStyleNames ); ++nId )
603 : : {
604 [ # # ]: 0 : if( nId != EXC_STYLE_NORMAL )
605 : : {
606 : 0 : OUString aShortName = rtl::OUString::createFromAscii(ppcStyleNames[nId]);
607 [ # # ][ # # ]: 0 : if( String(rStyleName).EqualsIgnoreCaseAscii( aShortName, nPrefixLen, aShortName.getLength() ) &&
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ][ # # ]
608 : 0 : (nNextChar < nPrefixLen + aShortName.getLength()))
609 : : {
610 : 0 : nFoundId = nId;
611 : 0 : nNextChar = nPrefixLen + aShortName.getLength();
612 : 0 : }
613 : : }
614 : : }
615 : : }
616 : :
617 [ # # ]: 0 : if( nNextChar > 0 )
618 : : {
619 [ # # ]: 0 : if( pnStyleId ) *pnStyleId = nFoundId;
620 [ # # ]: 0 : if( pnNextChar ) *pnNextChar = nNextChar;
621 : 0 : return true;
622 : : }
623 : :
624 [ # # ]: 0 : if( pnStyleId ) *pnStyleId = EXC_STYLE_USERDEF;
625 [ # # ]: 0 : if( pnNextChar ) *pnNextChar = 0;
626 : 0 : return nPrefixLen > 0; // also return true for unknown built-in styles
627 : : }
628 : :
629 : 0 : bool XclTools::GetBuiltInStyleId( sal_uInt8& rnStyleId, sal_uInt8& rnLevel, const OUString& rStyleName )
630 : : {
631 : : sal_uInt8 nStyleId;
632 : : sal_Int32 nNextChar;
633 [ # # ][ # # ]: 0 : if( IsBuiltInStyleName( rStyleName, &nStyleId, &nNextChar ) && (nStyleId != EXC_STYLE_USERDEF) )
[ # # ][ # # ]
634 : : {
635 [ # # ][ # # ]: 0 : if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
636 : : {
637 : 0 : OUString aLevel = rStyleName.copy(nNextChar);
638 : 0 : sal_Int32 nLevel = aLevel.toInt32();
639 [ # # ][ # # ]: 0 : if (OUString::valueOf(nLevel) == aLevel && nLevel > 0 && nLevel <= EXC_STYLE_LEVELCOUNT)
[ # # ][ # # ]
[ # # ]
640 : : {
641 : 0 : rnStyleId = nStyleId;
642 : 0 : rnLevel = static_cast< sal_uInt8 >( nLevel - 1 );
643 : 0 : return true;
644 [ # # ]: 0 : }
645 : : }
646 [ # # ]: 0 : else if( rStyleName.getLength() == nNextChar )
647 : : {
648 : 0 : rnStyleId = nStyleId;
649 : 0 : rnLevel = EXC_STYLE_NOLEVEL;
650 : 0 : return true;
651 : : }
652 : : }
653 : 0 : rnStyleId = EXC_STYLE_USERDEF;
654 : 0 : rnLevel = EXC_STYLE_NOLEVEL;
655 : 0 : return false;
656 : : }
657 : :
658 : : // conditional formatting style names -----------------------------------------
659 : :
660 : 8 : const OUString XclTools::maCFStyleNamePrefix1( RTL_CONSTASCII_USTRINGPARAM( "Excel_CondFormat_" ) );
661 : 8 : const OUString XclTools::maCFStyleNamePrefix2( RTL_CONSTASCII_USTRINGPARAM( "ConditionalStyle_" ) );
662 : :
663 : 0 : rtl::OUString XclTools::GetCondFormatStyleName( SCTAB nScTab, sal_Int32 nFormat, sal_uInt16 nCondition )
664 : : {
665 [ # # ]: 0 : rtl::OUStringBuffer aBuf(maCFStyleNamePrefix1);
666 [ # # ]: 0 : aBuf.append(static_cast<sal_Int32>(nScTab+1));
667 [ # # ]: 0 : aBuf.append(sal_Unicode('_'));
668 [ # # ]: 0 : aBuf.append(static_cast<sal_Int32>(nFormat+1));
669 [ # # ]: 0 : aBuf.append(sal_Unicode('_'));
670 [ # # ]: 0 : aBuf.append(static_cast<sal_Int32>(nCondition+1));
671 [ # # ]: 0 : return aBuf.makeStringAndClear();
672 : : }
673 : :
674 : 0 : bool XclTools::IsCondFormatStyleName( const OUString& rStyleName )
675 : : {
676 [ # # ][ # # ]: 0 : if( String(rStyleName).EqualsIgnoreCaseAscii( maCFStyleNamePrefix1, 0, maCFStyleNamePrefix1.getLength() ) )
[ # # ][ # # ]
677 : 0 : return true;
678 : :
679 [ # # ][ # # ]: 0 : if( String(rStyleName).EqualsIgnoreCaseAscii( maCFStyleNamePrefix2, 0, maCFStyleNamePrefix2.getLength() ) )
[ # # ][ # # ]
680 : 0 : return true;
681 : :
682 : 0 : return false;
683 : : }
684 : :
685 : : // stream handling ------------------------------------------------------------
686 : :
687 : 6 : void XclTools::SkipSubStream( XclImpStream& rStrm )
688 : : {
689 : 6 : bool bLoop = true;
690 [ + + ][ + - ]: 735 : while( bLoop && rStrm.StartNextRecord() )
[ + + ]
691 : : {
692 : 729 : sal_uInt16 nRecId = rStrm.GetRecId();
693 : 729 : bLoop = nRecId != EXC_ID_EOF;
694 [ + - ][ + - ]: 729 : if( (nRecId == EXC_ID2_BOF) || (nRecId == EXC_ID3_BOF) || (nRecId == EXC_ID4_BOF) || (nRecId == EXC_ID5_BOF) )
[ - + ][ + - ]
695 : 0 : SkipSubStream( rStrm );
696 : : }
697 : 6 : }
698 : :
699 : : // Basic macro names ----------------------------------------------------------
700 : :
701 : 8 : const OUString XclTools::maSbMacroPrefix( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:" ) );
702 : 8 : const OUString XclTools::maSbMacroSuffix( RTL_CONSTASCII_USTRINGPARAM( "?language=Basic&location=document" ) );
703 : :
704 : 0 : OUString XclTools::GetSbMacroUrl( const OUString& rMacroName, SfxObjectShell* pDocShell )
705 : : {
706 : : OSL_ENSURE( !rMacroName.isEmpty(), "XclTools::GetSbMacroUrl - macro name is empty" );
707 [ # # ]: 0 : ::ooo::vba::MacroResolvedInfo aMacroInfo = ::ooo::vba::resolveVBAMacro( pDocShell, rMacroName, false );
708 [ # # ]: 0 : if( aMacroInfo.mbFound )
709 [ # # ][ # # ]: 0 : return ::ooo::vba::makeMacroURL( aMacroInfo.msResolvedMacro );
[ # # ]
710 [ # # ]: 0 : return OUString();
711 : : }
712 : :
713 : 0 : OUString XclTools::GetXclMacroName( const OUString& rSbMacroUrl )
714 : : {
715 : 0 : sal_Int32 nSbMacroUrlLen = rSbMacroUrl.getLength();
716 : 0 : sal_Int32 nMacroNameLen = nSbMacroUrlLen - maSbMacroPrefix.getLength() - maSbMacroSuffix.getLength();
717 [ # # # # ]: 0 : if( (nMacroNameLen > 0) && rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroPrefix, 0 ) &&
[ # # ][ # # ]
718 : 0 : rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroSuffix, nSbMacroUrlLen - maSbMacroSuffix.getLength() ) )
719 : : {
720 : 0 : sal_Int32 nPrjDot = rSbMacroUrl.indexOf( '.', maSbMacroPrefix.getLength() ) + 1;
721 : 0 : return rSbMacroUrl.copy( nPrjDot, nSbMacroUrlLen - nPrjDot - maSbMacroSuffix.getLength() );
722 : : }
723 : 0 : return rtl::OUString();
724 : : }
725 : :
726 : : // read/write colors ----------------------------------------------------------
727 : :
728 : 1779 : XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor )
729 : : {
730 : : sal_uInt8 nR, nG, nB, nD;
731 [ + - ][ + - ]: 1779 : rStrm >> nR >> nG >> nB >> nD;
[ + - ][ + - ]
732 : 1779 : rColor.SetColor( RGB_COLORDATA( nR, nG, nB ) );
733 : 1779 : return rStrm;
734 : : }
735 : :
736 : 0 : XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor )
737 : : {
738 : 0 : return rStrm << rColor.GetRed() << rColor.GetGreen() << rColor.GetBlue() << sal_uInt8( 0 );
739 [ + - ][ + - ]: 24 : }
740 : :
741 : : // ============================================================================
742 : :
743 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|