1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <sal/mathconf.h>
24 #include <unotools/fontcvt.hxx>
25 #include <sfx2/objsh.hxx>
26 #include <sal/macros.h>
27 #include <editeng/editstat.hxx>
28 #include <filter/msfilter/msvbahelper.hxx>
29 #include "xestream.hxx"
30 #include "document.hxx"
32 #include "editutil.hxx"
33 #include "formula/errorcodes.hxx"
34 #include "globstr.hrc"
35 #include "xlstyle.hxx"
37 #include "xistream.hxx"
39 #include "xltools.hxx"
42 // GUID import/export =========================================================
46 ::std::fill( mpnData
, STATIC_ARRAY_END( mpnData
), 0 );
50 sal_uInt32 nData1
, sal_uInt16 nData2
, sal_uInt16 nData3
,
51 sal_uInt8 nData41
, sal_uInt8 nData42
, sal_uInt8 nData43
, sal_uInt8 nData44
,
52 sal_uInt8 nData45
, sal_uInt8 nData46
, sal_uInt8 nData47
, sal_uInt8 nData48
)
54 // convert to little endian -> makes streaming easy
55 UInt32ToSVBT32( nData1
, mpnData
);
56 ShortToSVBT16( nData2
, mpnData
+ 4 );
57 ShortToSVBT16( nData3
, mpnData
+ 6 );
58 mpnData
[ 8 ] = nData41
;
59 mpnData
[ 9 ] = nData42
;
60 mpnData
[ 10 ] = nData43
;
61 mpnData
[ 11 ] = nData44
;
62 mpnData
[ 12 ] = nData45
;
63 mpnData
[ 13 ] = nData46
;
64 mpnData
[ 14 ] = nData47
;
65 mpnData
[ 15 ] = nData48
;
68 bool operator==( const XclGuid
& rCmp1
, const XclGuid
& rCmp2
)
70 return ::std::equal( rCmp1
.mpnData
, STATIC_ARRAY_END( rCmp1
.mpnData
), rCmp2
.mpnData
);
73 bool operator<( const XclGuid
& rCmp1
, const XclGuid
& rCmp2
)
75 return ::std::lexicographical_compare(
76 rCmp1
.mpnData
, STATIC_ARRAY_END( rCmp1
.mpnData
),
77 rCmp2
.mpnData
, STATIC_ARRAY_END( rCmp2
.mpnData
) );
80 XclImpStream
& operator>>( XclImpStream
& rStrm
, XclGuid
& rGuid
)
82 rStrm
.Read( rGuid
.mpnData
, 16 ); // mpnData always in little endian
86 XclExpStream
& operator<<( XclExpStream
& rStrm
, const XclGuid
& rGuid
)
88 rStrm
.Write( rGuid
.mpnData
, 16 ); // mpnData already in little endian
92 // Excel Tools ================================================================
94 // GUID's ---------------------------------------------------------------------
96 const XclGuid
XclTools::maGuidStdLink(
97 0x79EAC9D0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
99 const XclGuid
XclTools::maGuidUrlMoniker(
100 0x79EAC9E0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
102 const XclGuid
XclTools::maGuidFileMoniker(
103 0x00000303, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
105 // numeric conversion ---------------------------------------------------------
107 double XclTools::GetDoubleFromRK( sal_Int32 nRKValue
)
116 if( ::get_flag( nRKValue
, EXC_RK_INTFLAG
) )
118 sal_Int32 nTemp
= nRKValue
>> 2;
119 ::set_flag
< sal_Int32
>( nTemp
, 0xE0000000, nRKValue
< 0 );
124 smD
.w32_parts
.msw
= nRKValue
& EXC_RK_VALUEMASK
;
127 if( ::get_flag( nRKValue
, EXC_RK_100FLAG
) )
133 bool XclTools::GetRKFromDouble( sal_Int32
& rnRKValue
, double fValue
)
138 fFrac
= modf( fValue
, &fInt
);
139 if( (fFrac
== 0.0) && (fInt
>= -536870912.0) && (fInt
<= 536870911.0) ) // 2^29
141 rnRKValue
= static_cast< sal_Int32
>( fInt
);
143 rnRKValue
|= EXC_RK_INT
;
148 fFrac
= modf( fValue
* 100.0, &fInt
);
149 if( (fFrac
== 0.0) && (fInt
>= -536870912.0) && (fInt
<= 536870911.0) )
151 rnRKValue
= static_cast< sal_Int32
>( fInt
);
153 rnRKValue
|= EXC_RK_INT100
;
161 sal_Int32
XclTools::GetScRotation( sal_uInt16 nXclRot
, sal_Int32 nRotForStacked
)
163 if( nXclRot
== EXC_ROT_STACKED
)
164 return nRotForStacked
;
165 OSL_ENSURE( nXclRot
<= 180, "XclTools::GetScRotation - illegal rotation angle" );
166 return static_cast< sal_Int32
>( (nXclRot
<= 180) ? (100 * ((nXclRot
> 90) ? (450 - nXclRot
) : nXclRot
)) : 0 );
169 sal_uInt8
XclTools::GetXclRotation( sal_Int32 nScRot
)
171 sal_Int32 nXclRot
= nScRot
/ 100;
172 if( (0 <= nXclRot
) && (nXclRot
<= 90) )
173 return static_cast< sal_uInt8
>( nXclRot
);
175 return static_cast< sal_uInt8
>( 270 - nXclRot
);
177 return static_cast< sal_uInt8
>( nXclRot
- 180 );
179 return static_cast< sal_uInt8
>( 450 - nXclRot
);
183 sal_uInt8
XclTools::GetXclRotFromOrient( sal_uInt8 nXclOrient
)
187 case EXC_ORIENT_NONE
: return EXC_ROT_NONE
;
188 case EXC_ORIENT_STACKED
: return EXC_ROT_STACKED
;
189 case EXC_ORIENT_90CCW
: return EXC_ROT_90CCW
;
190 case EXC_ORIENT_90CW
: return EXC_ROT_90CW
;
191 default: OSL_FAIL( "XclTools::GetXclRotFromOrient - unknown text orientation" );
196 sal_uInt8
XclTools::GetXclOrientFromRot( sal_uInt16 nXclRot
)
198 if( nXclRot
== EXC_ROT_STACKED
)
199 return EXC_ORIENT_STACKED
;
200 OSL_ENSURE( nXclRot
<= 180, "XclTools::GetXclOrientFromRot - unknown text rotation" );
201 if( (45 < nXclRot
) && (nXclRot
<= 90) )
202 return EXC_ORIENT_90CCW
;
203 if( (135 < nXclRot
) && (nXclRot
<= 180) )
204 return EXC_ORIENT_90CW
;
205 return EXC_ORIENT_NONE
;
208 sal_uInt8
XclTools::GetXclErrorCode( sal_uInt16 nScError
)
210 using namespace ScErrorCodes
;
213 case errIllegalArgument
: return EXC_ERR_VALUE
;
214 case errIllegalFPOperation
: return EXC_ERR_NUM
; // maybe DIV/0 or NUM...
215 case errDivisionByZero
: return EXC_ERR_DIV0
;
216 case errIllegalParameter
: return EXC_ERR_VALUE
;
217 case errPairExpected
: return EXC_ERR_VALUE
;
218 case errOperatorExpected
: return EXC_ERR_VALUE
;
219 case errVariableExpected
: return EXC_ERR_VALUE
;
220 case errParameterExpected
: return EXC_ERR_VALUE
;
221 case errNoValue
: return EXC_ERR_VALUE
;
222 case errCircularReference
: return EXC_ERR_VALUE
;
223 case errNoCode
: return EXC_ERR_NULL
;
224 case errNoRef
: return EXC_ERR_REF
;
225 case errNoName
: return EXC_ERR_NAME
;
226 case errNoAddin
: return EXC_ERR_NAME
;
227 case errNoMacro
: return EXC_ERR_NAME
;
228 case NOTAVAILABLE
: return EXC_ERR_NA
;
233 sal_uInt16
XclTools::GetScErrorCode( sal_uInt8 nXclError
)
235 using namespace ScErrorCodes
;
238 case EXC_ERR_NULL
: return errNoCode
;
239 case EXC_ERR_DIV0
: return errDivisionByZero
;
240 case EXC_ERR_VALUE
: return errNoValue
;
241 case EXC_ERR_REF
: return errNoRef
;
242 case EXC_ERR_NAME
: return errNoName
;
243 case EXC_ERR_NUM
: return errIllegalFPOperation
;
244 case EXC_ERR_NA
: return NOTAVAILABLE
;
245 default: OSL_FAIL( "XclTools::GetScErrorCode - unknown error code" );
250 double XclTools::ErrorToDouble( sal_uInt8 nXclError
)
257 ::rtl::math::setNan( &fVal
);
258 smD
.nan_parts
.fraction_lo
= GetScErrorCode( nXclError
);
262 XclBoolError
XclTools::ErrorToEnum( double& rfDblValue
, sal_uInt8 bErrOrBool
, sal_uInt8 nValue
)
270 case EXC_ERR_NULL
: eType
= xlErrNull
; break;
271 case EXC_ERR_DIV0
: eType
= xlErrDiv0
; break;
272 case EXC_ERR_VALUE
: eType
= xlErrValue
; break;
273 case EXC_ERR_REF
: eType
= xlErrRef
; break;
274 case EXC_ERR_NAME
: eType
= xlErrName
; break;
275 case EXC_ERR_NUM
: eType
= xlErrNum
; break;
276 case EXC_ERR_NA
: eType
= xlErrNA
; break;
277 default: eType
= xlErrUnknown
;
284 eType
= nValue
? xlErrTrue
: xlErrFalse
;
285 rfDblValue
= nValue
? 1.0 : 0.0;
290 sal_uInt16
XclTools::GetTwipsFromInch( double fInches
)
292 return static_cast< sal_uInt16
>(
293 ::std::min( ::std::max( (fInches
* EXC_TWIPS_PER_INCH
+ 0.5), 0.0 ), 65535.0 ) );
296 sal_uInt16
XclTools::GetTwipsFromHmm( sal_Int32 nHmm
)
298 return GetTwipsFromInch( static_cast< double >( nHmm
) / 1000.0 / CM_PER_INCH
);
301 double XclTools::GetInchFromTwips( sal_Int32 nTwips
)
303 return static_cast< double >( nTwips
) / EXC_TWIPS_PER_INCH
;
306 double XclTools::GetInchFromHmm( sal_Int32 nHmm
)
308 return GetInchFromTwips( GetTwipsFromHmm( nHmm
) );
311 sal_Int32
XclTools::GetHmmFromInch( double fInches
)
313 return static_cast< sal_Int32
>( fInches
* CM_PER_INCH
* 1000 );
316 sal_Int32
XclTools::GetHmmFromTwips( sal_Int32 nTwips
)
318 return GetHmmFromInch( GetInchFromTwips( nTwips
) );
321 sal_uInt16
XclTools::GetScColumnWidth( sal_uInt16 nXclWidth
, long nScCharWidth
)
323 double fScWidth
= static_cast< double >( nXclWidth
) / 256.0 * nScCharWidth
+ 0.5;
324 return limit_cast
< sal_uInt16
>( fScWidth
);
327 sal_uInt16
XclTools::GetXclColumnWidth( sal_uInt16 nScWidth
, long nScCharWidth
)
329 double fXclWidth
= static_cast< double >( nScWidth
) * 256.0 / nScCharWidth
+ 0.5;
330 return limit_cast
< sal_uInt16
>( fXclWidth
);
333 double XclTools::GetXclDefColWidthCorrection( long nXclDefFontHeight
)
335 return 40960.0 / ::std::max( nXclDefFontHeight
- 15L, 60L ) + 50.0;
338 // formatting -----------------------------------------------------------------
340 Color
XclTools::GetPatternColor( const Color
& rPattColor
, const Color
& rBackColor
, sal_uInt16 nXclPattern
)
342 // 0x00 == 0% transparence (full rPattColor)
343 // 0x80 == 100% transparence (full rBackColor)
344 static const sal_uInt8 pnRatioTable
[] =
346 0x80, 0x00, 0x40, 0x20, 0x60, 0x40, 0x40, 0x40, // 00 - 07
347 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15
348 0x50, 0x70, 0x78 // 16 - 18
350 return (nXclPattern
< SAL_N_ELEMENTS( pnRatioTable
)) ?
351 ScfTools::GetMixedColor( rPattColor
, rBackColor
, pnRatioTable
[ nXclPattern
] ) : rPattColor
;
354 // text encoding --------------------------------------------------------------
358 const struct XclCodePageEntry
360 sal_uInt16 mnCodePage
;
361 rtl_TextEncoding meTextEnc
;
365 { 437, RTL_TEXTENCODING_IBM_437
}, // OEM US
366 // { 720, RTL_TEXTENCODING_IBM_720 }, // OEM Arabic
367 { 737, RTL_TEXTENCODING_IBM_737
}, // OEM Greek
368 { 775, RTL_TEXTENCODING_IBM_775
}, // OEM Baltic
369 { 850, RTL_TEXTENCODING_IBM_850
}, // OEM Latin I
370 { 852, RTL_TEXTENCODING_IBM_852
}, // OEM Latin II (Central European)
371 { 855, RTL_TEXTENCODING_IBM_855
}, // OEM Cyrillic
372 { 857, RTL_TEXTENCODING_IBM_857
}, // OEM Turkish
373 // { 858, RTL_TEXTENCODING_IBM_858 }, // OEM Multilingual Latin I with Euro
374 { 860, RTL_TEXTENCODING_IBM_860
}, // OEM Portugese
375 { 861, RTL_TEXTENCODING_IBM_861
}, // OEM Icelandic
376 { 862, RTL_TEXTENCODING_IBM_862
}, // OEM Hebrew
377 { 863, RTL_TEXTENCODING_IBM_863
}, // OEM Canadian (French)
378 { 864, RTL_TEXTENCODING_IBM_864
}, // OEM Arabic
379 { 865, RTL_TEXTENCODING_IBM_865
}, // OEM Nordic
380 { 866, RTL_TEXTENCODING_IBM_866
}, // OEM Cyrillic (Russian)
381 { 869, RTL_TEXTENCODING_IBM_869
}, // OEM Greek (Modern)
382 { 874, RTL_TEXTENCODING_MS_874
}, // MS Windows Thai
383 { 932, RTL_TEXTENCODING_MS_932
}, // MS Windows Japanese Shift-JIS
384 { 936, RTL_TEXTENCODING_MS_936
}, // MS Windows Chinese Simplified GBK
385 { 949, RTL_TEXTENCODING_MS_949
}, // MS Windows Korean (Wansung)
386 { 950, RTL_TEXTENCODING_MS_950
}, // MS Windows Chinese Traditional BIG5
387 { 1200, RTL_TEXTENCODING_DONTKNOW
}, // Unicode (BIFF8) - return *_DONTKNOW to preserve old code page
388 { 1250, RTL_TEXTENCODING_MS_1250
}, // MS Windows Latin II (Central European)
389 { 1251, RTL_TEXTENCODING_MS_1251
}, // MS Windows Cyrillic
390 { 1252, RTL_TEXTENCODING_MS_1252
}, // MS Windows Latin I (BIFF4-BIFF8)
391 { 1253, RTL_TEXTENCODING_MS_1253
}, // MS Windows Greek
392 { 1254, RTL_TEXTENCODING_MS_1254
}, // MS Windows Turkish
393 { 1255, RTL_TEXTENCODING_MS_1255
}, // MS Windows Hebrew
394 { 1256, RTL_TEXTENCODING_MS_1256
}, // MS Windows Arabic
395 { 1257, RTL_TEXTENCODING_MS_1257
}, // MS Windows Baltic
396 { 1258, RTL_TEXTENCODING_MS_1258
}, // MS Windows Vietnamese
397 { 1361, RTL_TEXTENCODING_MS_1361
}, // MS Windows Korean (Johab)
398 { 10000, RTL_TEXTENCODING_APPLE_ROMAN
}, // Apple Roman
399 { 32768, RTL_TEXTENCODING_APPLE_ROMAN
}, // Apple Roman
400 { 32769, RTL_TEXTENCODING_MS_1252
} // MS Windows Latin I (BIFF2-BIFF3)
402 const XclCodePageEntry
* const pCodePageTableEnd
= STATIC_ARRAY_END( pCodePageTable
);
404 struct XclCodePageEntry_CPPred
406 inline explicit XclCodePageEntry_CPPred( sal_uInt16 nCodePage
) : mnCodePage( nCodePage
) {}
407 inline bool operator()( const XclCodePageEntry
& rEntry
) const { return rEntry
.mnCodePage
== mnCodePage
; }
408 sal_uInt16 mnCodePage
;
411 struct XclCodePageEntry_TEPred
413 inline explicit XclCodePageEntry_TEPred( rtl_TextEncoding eTextEnc
) : meTextEnc( eTextEnc
) {}
414 inline bool operator()( const XclCodePageEntry
& rEntry
) const { return rEntry
.meTextEnc
== meTextEnc
; }
415 rtl_TextEncoding meTextEnc
;
420 rtl_TextEncoding
XclTools::GetTextEncoding( sal_uInt16 nCodePage
)
422 const XclCodePageEntry
* pEntry
= ::std::find_if( pCodePageTable
, pCodePageTableEnd
, XclCodePageEntry_CPPred( nCodePage
) );
423 if( pEntry
== pCodePageTableEnd
)
425 OSL_TRACE( "XclTools::GetTextEncoding - unknown code page: 0x%04hX (%d)", nCodePage
, nCodePage
);
426 return RTL_TEXTENCODING_DONTKNOW
;
428 return pEntry
->meTextEnc
;
431 sal_uInt16
XclTools::GetXclCodePage( rtl_TextEncoding eTextEnc
)
433 if( eTextEnc
== RTL_TEXTENCODING_UNICODE
)
434 return 1200; // for BIFF8
436 const XclCodePageEntry
* pEntry
= ::std::find_if( pCodePageTable
, pCodePageTableEnd
, XclCodePageEntry_TEPred( eTextEnc
) );
437 if( pEntry
== pCodePageTableEnd
)
439 OSL_TRACE( "XclTools::GetXclCodePage - unsupported text encoding: %d", eTextEnc
);
442 return pEntry
->mnCodePage
;
445 // font names -----------------------------------------------------------------
447 OUString
XclTools::GetXclFontName( const OUString
& rFontName
)
449 // substitute with MS fonts
450 OUString aNewName
= GetSubsFontName(rFontName
, SUBSFONT_ONLYONE
| SUBSFONT_MS
);
451 return aNewName
.isEmpty() ? rFontName
: aNewName
;
454 // built-in defined names -----------------------------------------------------
456 const OUString
XclTools::maDefNamePrefix( "Excel_BuiltIn_" );
458 const OUString
XclTools::maDefNamePrefixXml ( "_xlnm." );
460 static const sal_Char
* const ppcDefNames
[] =
478 OUString
XclTools::GetXclBuiltInDefName( sal_Unicode cBuiltIn
)
480 OSL_ENSURE( SAL_N_ELEMENTS( ppcDefNames
) == EXC_BUILTIN_UNKNOWN
,
481 "XclTools::GetXclBuiltInDefName - built-in defined name list modified" );
483 if( cBuiltIn
< SAL_N_ELEMENTS( ppcDefNames
) )
484 return OUString::createFromAscii(ppcDefNames
[cBuiltIn
]);
486 return OUString::number(cBuiltIn
);
489 OUString
XclTools::GetBuiltInDefName( sal_Unicode cBuiltIn
)
491 OUStringBuffer
aBuf(maDefNamePrefix
);
492 aBuf
.append(GetXclBuiltInDefName(cBuiltIn
));
493 return aBuf
.makeStringAndClear();
496 OUString
XclTools::GetBuiltInDefNameXml( sal_Unicode cBuiltIn
)
498 OUStringBuffer
aBuf(maDefNamePrefixXml
);
499 aBuf
.append(GetXclBuiltInDefName(cBuiltIn
));
500 return aBuf
.makeStringAndClear();
503 sal_Unicode
XclTools::GetBuiltInDefNameIndex( const OUString
& rDefName
)
505 sal_Int32 nPrefixLen
= maDefNamePrefix
.getLength();
506 if( String(rDefName
).EqualsIgnoreCaseAscii( maDefNamePrefix
, 0, nPrefixLen
) )
508 for( sal_Unicode cBuiltIn
= 0; cBuiltIn
< EXC_BUILTIN_UNKNOWN
; ++cBuiltIn
)
510 OUString
aBuiltInName(GetXclBuiltInDefName(cBuiltIn
));
511 sal_Int32 nBuiltInLen
= aBuiltInName
.getLength();
512 if( String(rDefName
).EqualsIgnoreCaseAscii( aBuiltInName
, nPrefixLen
, nBuiltInLen
) )
514 // name can be followed by underline or space character
515 xub_StrLen nNextCharPos
= nPrefixLen
+ nBuiltInLen
;
516 sal_Unicode cNextChar
= (rDefName
.getLength() > nNextCharPos
) ? rDefName
.getStr()[nNextCharPos
] : '\0';
517 if( (cNextChar
== '\0') || (cNextChar
== ' ') || (cNextChar
== '_') )
522 return EXC_BUILTIN_UNKNOWN
;
525 // built-in style names -------------------------------------------------------
527 const OUString
XclTools::maStyleNamePrefix1( "Excel_BuiltIn_" );
528 const OUString
XclTools::maStyleNamePrefix2( "Excel Built-in " );
530 static const sal_Char
* const ppcStyleNames
[] =
532 "", // "Normal" not used directly, but localized "Default"
533 "RowLevel_", // outline level will be appended
534 "ColumnLevel_", // outline level will be appended
544 OUString
XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId
, const OUString
& rName
, sal_uInt8 nLevel
)
548 if( nStyleId
== EXC_STYLE_NORMAL
) // "Normal" becomes "Default" style
550 aStyleName
= ScGlobal::GetRscString( STR_STYLENAME_STANDARD
);
554 OUStringBuffer
aBuf(maStyleNamePrefix1
);
555 if( nStyleId
< SAL_N_ELEMENTS( ppcStyleNames
) )
556 aBuf
.appendAscii(ppcStyleNames
[nStyleId
]);
557 else if (!rName
.isEmpty())
560 aBuf
.append(static_cast<sal_Int32
>(nStyleId
));
562 if( (nStyleId
== EXC_STYLE_ROWLEVEL
) || (nStyleId
== EXC_STYLE_COLLEVEL
) )
563 aBuf
.append(static_cast<sal_Int32
>(nLevel
+1));
565 aStyleName
= aBuf
.makeStringAndClear();
571 bool XclTools::IsBuiltInStyleName( const OUString
& rStyleName
, sal_uInt8
* pnStyleId
, sal_Int32
* pnNextChar
)
573 // "Default" becomes "Normal"
574 if (rStyleName
.equals(ScGlobal::GetRscString(STR_STYLENAME_STANDARD
)))
576 if( pnStyleId
) *pnStyleId
= EXC_STYLE_NORMAL
;
577 if( pnNextChar
) *pnNextChar
= rStyleName
.getLength();
581 // try the other built-in styles
582 sal_uInt8 nFoundId
= 0;
583 sal_Int32 nNextChar
= 0;
585 sal_Int32 nPrefixLen
= 0;
586 if( String(rStyleName
).EqualsIgnoreCaseAscii( maStyleNamePrefix1
, 0, maStyleNamePrefix1
.getLength() ) )
587 nPrefixLen
= maStyleNamePrefix1
.getLength();
588 else if( String(rStyleName
).EqualsIgnoreCaseAscii( maStyleNamePrefix2
, 0, maStyleNamePrefix2
.getLength() ) )
589 nPrefixLen
= maStyleNamePrefix2
.getLength();
592 for( sal_uInt8 nId
= 0; nId
< SAL_N_ELEMENTS( ppcStyleNames
); ++nId
)
594 if( nId
!= EXC_STYLE_NORMAL
)
596 OUString aShortName
= OUString::createFromAscii(ppcStyleNames
[nId
]);
597 if( String(rStyleName
).EqualsIgnoreCaseAscii( aShortName
, nPrefixLen
, aShortName
.getLength() ) &&
598 (nNextChar
< nPrefixLen
+ aShortName
.getLength()))
601 nNextChar
= nPrefixLen
+ aShortName
.getLength();
609 if( pnStyleId
) *pnStyleId
= nFoundId
;
610 if( pnNextChar
) *pnNextChar
= nNextChar
;
614 if( pnStyleId
) *pnStyleId
= EXC_STYLE_USERDEF
;
615 if( pnNextChar
) *pnNextChar
= 0;
616 return nPrefixLen
> 0; // also return true for unknown built-in styles
619 bool XclTools::GetBuiltInStyleId( sal_uInt8
& rnStyleId
, sal_uInt8
& rnLevel
, const OUString
& rStyleName
)
623 if( IsBuiltInStyleName( rStyleName
, &nStyleId
, &nNextChar
) && (nStyleId
!= EXC_STYLE_USERDEF
) )
625 if( (nStyleId
== EXC_STYLE_ROWLEVEL
) || (nStyleId
== EXC_STYLE_COLLEVEL
) )
627 OUString aLevel
= rStyleName
.copy(nNextChar
);
628 sal_Int32 nLevel
= aLevel
.toInt32();
629 if (OUString::valueOf(nLevel
) == aLevel
&& nLevel
> 0 && nLevel
<= EXC_STYLE_LEVELCOUNT
)
631 rnStyleId
= nStyleId
;
632 rnLevel
= static_cast< sal_uInt8
>( nLevel
- 1 );
636 else if( rStyleName
.getLength() == nNextChar
)
638 rnStyleId
= nStyleId
;
639 rnLevel
= EXC_STYLE_NOLEVEL
;
643 rnStyleId
= EXC_STYLE_USERDEF
;
644 rnLevel
= EXC_STYLE_NOLEVEL
;
648 // conditional formatting style names -----------------------------------------
650 const OUString
XclTools::maCFStyleNamePrefix1( "Excel_CondFormat_" );
651 const OUString
XclTools::maCFStyleNamePrefix2( "ConditionalStyle_" );
653 OUString
XclTools::GetCondFormatStyleName( SCTAB nScTab
, sal_Int32 nFormat
, sal_uInt16 nCondition
)
655 OUStringBuffer
aBuf(maCFStyleNamePrefix1
);
656 aBuf
.append(static_cast<sal_Int32
>(nScTab
+1));
657 aBuf
.append(sal_Unicode('_'));
658 aBuf
.append(static_cast<sal_Int32
>(nFormat
+1));
659 aBuf
.append(sal_Unicode('_'));
660 aBuf
.append(static_cast<sal_Int32
>(nCondition
+1));
661 return aBuf
.makeStringAndClear();
664 bool XclTools::IsCondFormatStyleName( const OUString
& rStyleName
)
666 if( String(rStyleName
).EqualsIgnoreCaseAscii( maCFStyleNamePrefix1
, 0, maCFStyleNamePrefix1
.getLength() ) )
669 if( String(rStyleName
).EqualsIgnoreCaseAscii( maCFStyleNamePrefix2
, 0, maCFStyleNamePrefix2
.getLength() ) )
675 // stream handling ------------------------------------------------------------
677 void XclTools::SkipSubStream( XclImpStream
& rStrm
)
680 while( bLoop
&& rStrm
.StartNextRecord() )
682 sal_uInt16 nRecId
= rStrm
.GetRecId();
683 bLoop
= nRecId
!= EXC_ID_EOF
;
684 if( (nRecId
== EXC_ID2_BOF
) || (nRecId
== EXC_ID3_BOF
) || (nRecId
== EXC_ID4_BOF
) || (nRecId
== EXC_ID5_BOF
) )
685 SkipSubStream( rStrm
);
689 // Basic macro names ----------------------------------------------------------
691 const OUString
XclTools::maSbMacroPrefix( "vnd.sun.star.script:" );
692 const OUString
XclTools::maSbMacroSuffix( "?language=Basic&location=document" );
694 OUString
XclTools::GetSbMacroUrl( const OUString
& rMacroName
, SfxObjectShell
* pDocShell
)
696 OSL_ENSURE( !rMacroName
.isEmpty(), "XclTools::GetSbMacroUrl - macro name is empty" );
697 ::ooo::vba::MacroResolvedInfo aMacroInfo
= ::ooo::vba::resolveVBAMacro( pDocShell
, rMacroName
, false );
698 if( aMacroInfo
.mbFound
)
699 return ::ooo::vba::makeMacroURL( aMacroInfo
.msResolvedMacro
);
703 OUString
XclTools::GetXclMacroName( const OUString
& rSbMacroUrl
)
705 sal_Int32 nSbMacroUrlLen
= rSbMacroUrl
.getLength();
706 sal_Int32 nMacroNameLen
= nSbMacroUrlLen
- maSbMacroPrefix
.getLength() - maSbMacroSuffix
.getLength();
707 if( (nMacroNameLen
> 0) && rSbMacroUrl
.matchIgnoreAsciiCase( maSbMacroPrefix
, 0 ) &&
708 rSbMacroUrl
.matchIgnoreAsciiCase( maSbMacroSuffix
, nSbMacroUrlLen
- maSbMacroSuffix
.getLength() ) )
710 sal_Int32 nPrjDot
= rSbMacroUrl
.indexOf( '.', maSbMacroPrefix
.getLength() ) + 1;
711 return rSbMacroUrl
.copy( nPrjDot
, nSbMacroUrlLen
- nPrjDot
- maSbMacroSuffix
.getLength() );
716 // read/write colors ----------------------------------------------------------
718 XclImpStream
& operator>>( XclImpStream
& rStrm
, Color
& rColor
)
720 sal_uInt8 nR
, nG
, nB
, nD
;
721 rStrm
>> nR
>> nG
>> nB
>> nD
;
722 rColor
.SetColor( RGB_COLORDATA( nR
, nG
, nB
) );
726 XclExpStream
& operator<<( XclExpStream
& rStrm
, const Color
& rColor
)
728 return rStrm
<< rColor
.GetRed() << rColor
.GetGreen() << rColor
.GetBlue() << sal_uInt8( 0 );
731 // ============================================================================
733 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */