update dev300-m58
[ooovba.git] / sc / source / filter / excel / xltools.cxx
blobef38a0037ca0e5dd06f884b89d20dd90c9bf5354
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xltools.cxx,v $
10 * $Revision: 1.31.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include <algorithm>
35 #include <math.h>
36 #include <sal/mathconf.h>
37 #include <vcl/fontcvt.hxx>
38 #include <sfx2/objsh.hxx>
39 #include <svx/editstat.hxx>
40 #include "xestream.hxx"
41 #include "document.hxx"
42 #include "docuno.hxx"
43 #include "editutil.hxx"
44 #include "formula/errorcodes.hxx"
45 #include "globstr.hrc"
46 #include "xlstyle.hxx"
47 #include "xlname.hxx"
48 #include "xistream.hxx"
49 #include "xiroot.hxx"
50 #include "xltools.hxx"
52 // GUID import/export =========================================================
54 XclGuid::XclGuid()
56 ::std::fill( mpnData, STATIC_TABLE_END( mpnData ), 0 );
59 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 )
64 // convert to little endian -> makes streaming easy
65 UInt32ToSVBT32( nData1, mpnData );
66 ShortToSVBT16( nData2, mpnData + 4 );
67 ShortToSVBT16( nData3, mpnData + 6 );
68 mpnData[ 8 ] = nData41;
69 mpnData[ 9 ] = nData42;
70 mpnData[ 10 ] = nData43;
71 mpnData[ 11 ] = nData44;
72 mpnData[ 12 ] = nData45;
73 mpnData[ 13 ] = nData46;
74 mpnData[ 14 ] = nData47;
75 mpnData[ 15 ] = nData48;
78 bool operator==( const XclGuid& rCmp1, const XclGuid& rCmp2 )
80 return ::std::equal( rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ), rCmp2.mpnData );
83 bool operator<( const XclGuid& rCmp1, const XclGuid& rCmp2 )
85 return ::std::lexicographical_compare(
86 rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ),
87 rCmp2.mpnData, STATIC_TABLE_END( rCmp2.mpnData ) );
90 XclImpStream& operator>>( XclImpStream& rStrm, XclGuid& rGuid )
92 rStrm.Read( rGuid.mpnData, 16 ); // mpnData always in little endian
93 return rStrm;
96 XclExpStream& operator<<( XclExpStream& rStrm, const XclGuid& rGuid )
98 rStrm.Write( rGuid.mpnData, 16 ); // mpnData already in little endian
99 return rStrm;
102 // Excel Tools ================================================================
104 // GUID's ---------------------------------------------------------------------
106 const XclGuid XclTools::maGuidStdLink(
107 0x79EAC9D0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
109 const XclGuid XclTools::maGuidUrlMoniker(
110 0x79EAC9E0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
112 const XclGuid XclTools::maGuidFileMoniker(
113 0x00000303, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
115 // numeric conversion ---------------------------------------------------------
117 double XclTools::GetDoubleFromRK( sal_Int32 nRKValue )
119 double fVal = 0.0;
121 if( ::get_flag( nRKValue, EXC_RK_INTFLAG ) )
123 sal_Int32 nTemp = nRKValue >> 2;
124 ::set_flag< sal_Int32 >( nTemp, 0xE0000000, nRKValue < 0 );
125 fVal = nTemp;
127 else
129 sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &fVal );
130 pDouble->w32_parts.msw = nRKValue & EXC_RK_VALUEMASK;
133 if( ::get_flag( nRKValue, EXC_RK_100FLAG ) )
134 fVal /= 100.0;
136 return fVal;
139 bool XclTools::GetRKFromDouble( sal_Int32& rnRKValue, double fValue )
141 double fFrac, fInt;
143 // integer
144 fFrac = modf( fValue, &fInt );
145 if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) ) // 2^29
147 rnRKValue = static_cast< sal_Int32 >( fInt );
148 rnRKValue <<= 2;
149 rnRKValue |= EXC_RK_INT;
150 return true;
153 // integer/100
154 fFrac = modf( fValue * 100.0, &fInt );
155 if( (fFrac == 0.0) && (fInt >= -536870912.0) && (fInt <= 536870911.0) )
157 rnRKValue = static_cast< sal_Int32 >( fInt );
158 rnRKValue <<= 2;
159 rnRKValue |= EXC_RK_INT100;
160 return true;
163 // double
164 return false;
168 sal_uInt8 XclTools::GetXclErrorCode( USHORT nScError )
170 using namespace ScErrorCodes;
171 switch( nScError )
173 case errIllegalArgument: return EXC_ERR_VALUE;
174 case errIllegalFPOperation: return EXC_ERR_NUM; // maybe DIV/0 or NUM...
175 case errDivisionByZero: return EXC_ERR_DIV0;
176 case errIllegalParameter: return EXC_ERR_VALUE;
177 case errPairExpected: return EXC_ERR_VALUE;
178 case errOperatorExpected: return EXC_ERR_VALUE;
179 case errVariableExpected: return EXC_ERR_VALUE;
180 case errParameterExpected: return EXC_ERR_VALUE;
181 case errNoValue: return EXC_ERR_VALUE;
182 case errCircularReference: return EXC_ERR_VALUE;
183 case errNoCode: return EXC_ERR_NULL;
184 case errNoRef: return EXC_ERR_REF;
185 case errNoName: return EXC_ERR_NAME;
186 case errNoAddin: return EXC_ERR_NAME;
187 case errNoMacro: return EXC_ERR_NAME;
188 case NOTAVAILABLE: return EXC_ERR_NA;
190 return EXC_ERR_NA;
193 USHORT XclTools::GetScErrorCode( sal_uInt8 nXclError )
195 using namespace ScErrorCodes;
196 switch( nXclError )
198 case EXC_ERR_NULL: return errNoCode;
199 case EXC_ERR_DIV0: return errDivisionByZero;
200 case EXC_ERR_VALUE: return errNoValue;
201 case EXC_ERR_REF: return errNoRef;
202 case EXC_ERR_NAME: return errNoName;
203 case EXC_ERR_NUM: return errIllegalFPOperation;
204 case EXC_ERR_NA: return NOTAVAILABLE;
205 default: DBG_ERRORFILE( "XclTools::GetScErrorCode - unknown error code" );
207 return NOTAVAILABLE;
211 sal_Int32 XclTools::GetScRotation( sal_uInt16 nXclRot, sal_Int32 nRotForStacked )
213 if( nXclRot == EXC_ROT_STACKED )
214 return nRotForStacked;
215 DBG_ASSERT( nXclRot <= 180, "XclTools::GetScRotation - illegal rotation angle" );
216 return static_cast< sal_Int32 >( (nXclRot <= 180) ? (100 * ((nXclRot > 90) ? (450 - nXclRot) : nXclRot)) : 0 );
219 sal_uInt8 XclTools::GetXclRotation( sal_Int32 nScRot )
221 sal_Int32 nXclRot = nScRot / 100;
222 if( (0 <= nXclRot) && (nXclRot <= 90) )
223 return static_cast< sal_uInt8 >( nXclRot );
224 if( nXclRot < 180 )
225 return static_cast< sal_uInt8 >( 270 - nXclRot );
226 if( nXclRot < 270 )
227 return static_cast< sal_uInt8 >( nXclRot - 180 );
228 if( nXclRot < 360 )
229 return static_cast< sal_uInt8 >( 450 - nXclRot );
230 return 0;
233 sal_uInt8 XclTools::GetXclRotFromOrient( sal_uInt8 nXclOrient )
235 switch( nXclOrient )
237 case EXC_ORIENT_NONE: return EXC_ROT_NONE;
238 case EXC_ORIENT_STACKED: return EXC_ROT_STACKED;
239 case EXC_ORIENT_90CCW: return EXC_ROT_90CCW;
240 case EXC_ORIENT_90CW: return EXC_ROT_90CW;
241 default: DBG_ERRORFILE( "XclTools::GetXclRotFromOrient - unknown text orientation" );
243 return EXC_ROT_NONE;
246 sal_uInt8 XclTools::GetXclOrientFromRot( sal_uInt16 nXclRot )
248 if( nXclRot == EXC_ROT_STACKED )
249 return EXC_ORIENT_STACKED;
250 DBG_ASSERT( nXclRot <= 180, "XclTools::GetXclOrientFromRot - unknown text rotation" );
251 if( (45 < nXclRot) && (nXclRot <= 90) )
252 return EXC_ORIENT_90CCW;
253 if( (135 < nXclRot) && (nXclRot <= 180) )
254 return EXC_ORIENT_90CW;
255 return EXC_ORIENT_NONE;
259 XclBoolError XclTools::ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sal_uInt8 nValue )
261 XclBoolError eType;
262 if( bErrOrBool )
264 // error value
265 switch( nValue )
267 case EXC_ERR_NULL: eType = xlErrNull; break;
268 case EXC_ERR_DIV0: eType = xlErrDiv0; break;
269 case EXC_ERR_VALUE: eType = xlErrValue; break;
270 case EXC_ERR_REF: eType = xlErrRef; break;
271 case EXC_ERR_NAME: eType = xlErrName; break;
272 case EXC_ERR_NUM: eType = xlErrNum; break;
273 case EXC_ERR_NA: eType = xlErrNA; break;
274 default: eType = xlErrUnknown;
276 rfDblValue = 0.0;
278 else
280 // Boolean value
281 eType = nValue ? xlErrTrue : xlErrFalse;
282 rfDblValue = nValue ? 1.0 : 0.0;
284 return eType;
288 sal_uInt16 XclTools::GetTwipsFromInch( double fInches )
290 return static_cast< sal_uInt16 >(
291 ::std::min( ::std::max( (fInches * EXC_TWIPS_PER_INCH + 0.5), 0.0 ), 65535.0 ) );
294 sal_uInt16 XclTools::GetTwipsFromHmm( sal_Int32 nHmm )
296 return GetTwipsFromInch( static_cast< double >( nHmm ) / 1000.0 / CM_PER_INCH );
299 double XclTools::GetInchFromTwips( sal_Int32 nTwips )
301 return static_cast< double >( nTwips ) / EXC_TWIPS_PER_INCH;
304 double XclTools::GetInchFromHmm( sal_Int32 nHmm )
306 return GetInchFromTwips( GetTwipsFromHmm( nHmm ) );
309 sal_Int32 XclTools::GetHmmFromInch( double fInches )
311 return static_cast< sal_Int32 >( fInches * CM_PER_INCH * 1000 );
314 sal_Int32 XclTools::GetHmmFromTwips( sal_Int32 nTwips )
316 return GetHmmFromInch( GetInchFromTwips( nTwips ) );
319 USHORT XclTools::GetScColumnWidth( sal_uInt16 nXclWidth, long nScCharWidth )
321 double fScWidth = static_cast< double >( nXclWidth ) / 256.0 * nScCharWidth + 0.5;
322 return limit_cast< USHORT >( fScWidth );
325 sal_uInt16 XclTools::GetXclColumnWidth( USHORT nScWidth, long nScCharWidth )
327 double fXclWidth = static_cast< double >( nScWidth ) * 256.0 / nScCharWidth + 0.5;
328 return limit_cast< sal_uInt16 >( fXclWidth );
331 double XclTools::GetXclDefColWidthCorrection( long nXclDefFontHeight )
333 return 40960.0 / ::std::max( nXclDefFontHeight - 15L, 60L ) + 50.0;
336 // formatting -----------------------------------------------------------------
338 Color XclTools::GetPatternColor( const Color& rPattColor, const Color& rBackColor, sal_uInt16 nXclPattern )
340 // 0x00 == 0% transparence (full rPattColor)
341 // 0x80 == 100% transparence (full rBackColor)
342 static const sal_uInt8 pnRatioTable[] =
344 0x80, 0x00, 0x40, 0x20, 0x60, 0x40, 0x40, 0x40, // 00 - 07
345 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15
346 0x50, 0x70, 0x78 // 16 - 18
348 return (nXclPattern < STATIC_TABLE_SIZE( pnRatioTable )) ?
349 ScfTools::GetMixedColor( rPattColor, rBackColor, pnRatioTable[ nXclPattern ] ) : rPattColor;
352 // text encoding --------------------------------------------------------------
354 namespace {
356 const struct XclCodePageEntry
358 sal_uInt16 mnCodePage;
359 rtl_TextEncoding meTextEnc;
361 pCodePageTable[] =
363 { 437, RTL_TEXTENCODING_IBM_437 }, // OEM US
364 // { 720, RTL_TEXTENCODING_IBM_720 }, // OEM Arabic
365 { 737, RTL_TEXTENCODING_IBM_737 }, // OEM Greek
366 { 775, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic
367 { 850, RTL_TEXTENCODING_IBM_850 }, // OEM Latin I
368 { 852, RTL_TEXTENCODING_IBM_852 }, // OEM Latin II (Central European)
369 { 855, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic
370 { 857, RTL_TEXTENCODING_IBM_857 }, // OEM Turkish
371 // { 858, RTL_TEXTENCODING_IBM_858 }, // OEM Multilingual Latin I with Euro
372 { 860, RTL_TEXTENCODING_IBM_860 }, // OEM Portugese
373 { 861, RTL_TEXTENCODING_IBM_861 }, // OEM Icelandic
374 { 862, RTL_TEXTENCODING_IBM_862 }, // OEM Hebrew
375 { 863, RTL_TEXTENCODING_IBM_863 }, // OEM Canadian (French)
376 { 864, RTL_TEXTENCODING_IBM_864 }, // OEM Arabic
377 { 865, RTL_TEXTENCODING_IBM_865 }, // OEM Nordic
378 { 866, RTL_TEXTENCODING_IBM_866 }, // OEM Cyrillic (Russian)
379 { 869, RTL_TEXTENCODING_IBM_869 }, // OEM Greek (Modern)
380 { 874, RTL_TEXTENCODING_MS_874 }, // MS Windows Thai
381 { 932, RTL_TEXTENCODING_MS_932 }, // MS Windows Japanese Shift-JIS
382 { 936, RTL_TEXTENCODING_MS_936 }, // MS Windows Chinese Simplified GBK
383 { 949, RTL_TEXTENCODING_MS_949 }, // MS Windows Korean (Wansung)
384 { 950, RTL_TEXTENCODING_MS_950 }, // MS Windows Chinese Traditional BIG5
385 { 1200, RTL_TEXTENCODING_DONTKNOW }, // Unicode (BIFF8) - return *_DONTKNOW to preserve old code page
386 { 1250, RTL_TEXTENCODING_MS_1250 }, // MS Windows Latin II (Central European)
387 { 1251, RTL_TEXTENCODING_MS_1251 }, // MS Windows Cyrillic
388 { 1252, RTL_TEXTENCODING_MS_1252 }, // MS Windows Latin I (BIFF4-BIFF8)
389 { 1253, RTL_TEXTENCODING_MS_1253 }, // MS Windows Greek
390 { 1254, RTL_TEXTENCODING_MS_1254 }, // MS Windows Turkish
391 { 1255, RTL_TEXTENCODING_MS_1255 }, // MS Windows Hebrew
392 { 1256, RTL_TEXTENCODING_MS_1256 }, // MS Windows Arabic
393 { 1257, RTL_TEXTENCODING_MS_1257 }, // MS Windows Baltic
394 { 1258, RTL_TEXTENCODING_MS_1258 }, // MS Windows Vietnamese
395 { 1361, RTL_TEXTENCODING_MS_1361 }, // MS Windows Korean (Johab)
396 { 10000, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
397 { 32768, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
398 { 32769, RTL_TEXTENCODING_MS_1252 } // MS Windows Latin I (BIFF2-BIFF3)
400 const XclCodePageEntry* const pCodePageTableEnd = STATIC_TABLE_END( pCodePageTable );
402 struct XclCodePageEntry_CPPred
404 inline explicit XclCodePageEntry_CPPred( sal_uInt16 nCodePage ) : mnCodePage( nCodePage ) {}
405 inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.mnCodePage == mnCodePage; }
406 sal_uInt16 mnCodePage;
409 struct XclCodePageEntry_TEPred
411 inline explicit XclCodePageEntry_TEPred( rtl_TextEncoding eTextEnc ) : meTextEnc( eTextEnc ) {}
412 inline bool operator()( const XclCodePageEntry& rEntry ) const { return rEntry.meTextEnc == meTextEnc; }
413 rtl_TextEncoding meTextEnc;
416 } // namespace
418 rtl_TextEncoding XclTools::GetTextEncoding( sal_uInt16 nCodePage )
420 const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_CPPred( nCodePage ) );
421 if( pEntry == pCodePageTableEnd )
423 DBG_ERROR2( "XclTools::GetTextEncoding - unknown code page: 0x%04hX (%d)", nCodePage, nCodePage );
424 return RTL_TEXTENCODING_DONTKNOW;
426 return pEntry->meTextEnc;
429 //UNUSED2008-05 sal_uInt16 XclTools::GetXclCodePage( rtl_TextEncoding eTextEnc )
430 //UNUSED2008-05 {
431 //UNUSED2008-05 const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_TEPred( eTextEnc ) );
432 //UNUSED2008-05 if( pEntry == pCodePageTableEnd )
433 //UNUSED2008-05 {
434 //UNUSED2008-05 DBG_ERROR1( "XclTools::GetXclCodePage - unsupported text encoding: %d", eTextEnc );
435 //UNUSED2008-05 return 1252;
436 //UNUSED2008-05 }
437 //UNUSED2008-05 return pEntry->mnCodePage;
438 //UNUSED2008-05 }
440 // font names -----------------------------------------------------------------
442 String XclTools::GetXclFontName( const String& rFontName )
444 // #106246# substitute with MS fonts
445 String aNewName( GetSubsFontName( rFontName, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
446 if( aNewName.Len() )
447 return aNewName;
448 return rFontName;
451 // built-in defined names -----------------------------------------------------
453 const String XclTools::maDefNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
455 static const sal_Char* const ppcDefNames[] =
457 "Consolidate_Area",
458 "Auto_Open",
459 "Auto_Close",
460 "Extract",
461 "Database",
462 "Criteria",
463 "Print_Area",
464 "Print_Titles",
465 "Recorder",
466 "Data_Form",
467 "Auto_Activate",
468 "Auto_Deactivate",
469 "Sheet_Title",
470 "_FilterDatabase"
473 String XclTools::GetXclBuiltInDefName( sal_Unicode cBuiltIn )
475 DBG_ASSERT( STATIC_TABLE_SIZE( ppcDefNames ) == EXC_BUILTIN_UNKNOWN,
476 "XclTools::GetXclBuiltInDefName - built-in defined name list modified" );
477 String aDefName;
478 if( cBuiltIn < STATIC_TABLE_SIZE( ppcDefNames ) )
479 aDefName.AssignAscii( ppcDefNames[ cBuiltIn ] );
480 else
481 aDefName = String::CreateFromInt32( cBuiltIn );
482 return aDefName;
485 String XclTools::GetBuiltInDefName( sal_Unicode cBuiltIn )
487 return String( maDefNamePrefix ).Append( GetXclBuiltInDefName( cBuiltIn ) );
490 sal_Unicode XclTools::GetBuiltInDefNameIndex( const String& rDefName )
492 xub_StrLen nPrefixLen = maDefNamePrefix.Len();
493 if( rDefName.EqualsIgnoreCaseAscii( maDefNamePrefix, 0, nPrefixLen ) )
495 for( sal_Unicode cBuiltIn = 0; cBuiltIn < EXC_BUILTIN_UNKNOWN; ++cBuiltIn )
497 String aBuiltInName( GetXclBuiltInDefName( cBuiltIn ) );
498 xub_StrLen nBuiltInLen = aBuiltInName.Len();
499 if( rDefName.EqualsIgnoreCaseAscii( aBuiltInName, nPrefixLen, nBuiltInLen ) )
501 // name can be followed by underline or space character
502 xub_StrLen nNextCharPos = nPrefixLen + nBuiltInLen;
503 sal_Unicode cNextChar = (rDefName.Len() > nNextCharPos) ? rDefName.GetChar( nNextCharPos ) : '\0';
504 if( (cNextChar == '\0') || (cNextChar == ' ') || (cNextChar == '_') )
505 return cBuiltIn;
509 return EXC_BUILTIN_UNKNOWN;
512 // built-in style names -------------------------------------------------------
514 const String XclTools::maStyleNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "Excel_BuiltIn_" ) );
516 static const sal_Char* const ppcStyleNames[] =
518 "", // "Normal" not used directly, but localized "Default"
519 "RowLevel_", // outline level will be appended
520 "ColumnLevel_", // outline level will be appended
521 "Comma",
522 "Currency",
523 "Percent",
524 "Comma_0",
525 "Currency_0",
526 "Hyperlink",
527 "Followed_Hyperlink"
530 String XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId, sal_uInt8 nLevel )
532 String aStyleName;
534 if( nStyleId == EXC_STYLE_NORMAL ) // "Normal" becomes "Default" style
535 aStyleName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
536 else if( nStyleId < STATIC_TABLE_SIZE( ppcStyleNames ) )
537 aStyleName.Assign( maStyleNamePrefix ).AppendAscii( ppcStyleNames[ nStyleId ] );
539 if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
540 aStyleName.Append( String::CreateFromInt32( nLevel + 1 ) );
542 return aStyleName;
545 bool XclTools::IsBuiltInStyleName( const String& rStyleName, sal_uInt8* pnStyleId, xub_StrLen* pnNextChar )
547 // "Default" becomes "Normal"
548 if( rStyleName == ScGlobal::GetRscString( STR_STYLENAME_STANDARD ) )
550 if( pnStyleId ) *pnStyleId = EXC_STYLE_NORMAL;
551 if( pnNextChar ) *pnNextChar = rStyleName.Len();
552 return true;
555 // try the other built-in styles
556 xub_StrLen nPrefixLen = maStyleNamePrefix.Len();
557 sal_uInt8 nFoundId = 0;
558 xub_StrLen nNextChar = 0;
559 if( rStyleName.EqualsIgnoreCaseAscii( maStyleNamePrefix, 0, nPrefixLen ) )
561 String aShortName;
562 for( sal_uInt8 nId = 0; nId < STATIC_TABLE_SIZE( ppcStyleNames ); ++nId )
564 if( nId != EXC_STYLE_NORMAL )
566 aShortName.AssignAscii( ppcStyleNames[ nId ] );
567 if( rStyleName.EqualsIgnoreCaseAscii( aShortName, nPrefixLen, aShortName.Len() ) &&
568 (nNextChar < nPrefixLen + aShortName.Len()) )
570 nFoundId = nId;
571 nNextChar = nPrefixLen + aShortName.Len();
577 if( nNextChar > 0 )
579 if( pnStyleId ) *pnStyleId = nFoundId;
580 if( pnNextChar ) *pnNextChar = nNextChar;
581 return true;
584 if( pnStyleId ) *pnStyleId = EXC_STYLE_USERDEF;
585 if( pnNextChar ) *pnNextChar = 0;
586 return false;
589 bool XclTools::GetBuiltInStyleId( sal_uInt8& rnStyleId, sal_uInt8& rnLevel, const String& rStyleName )
591 sal_uInt8 nStyleId;
592 xub_StrLen nNextChar;
593 if( IsBuiltInStyleName( rStyleName, &nStyleId, &nNextChar ) )
595 if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) )
597 String aLevel( rStyleName, nNextChar, STRING_LEN );
598 sal_Int32 nLevel = aLevel.ToInt32();
599 if( (String::CreateFromInt32( nLevel ) == aLevel) && (nLevel > 0) && (nLevel <= EXC_STYLE_LEVELCOUNT) )
601 rnStyleId = nStyleId;
602 rnLevel = static_cast< sal_uInt8 >( nLevel - 1 );
603 return true;
606 else if( rStyleName.Len() == nNextChar )
608 rnStyleId = nStyleId;
609 rnLevel = EXC_STYLE_NOLEVEL;
610 return true;
613 rnStyleId = EXC_STYLE_USERDEF;
614 rnLevel = EXC_STYLE_NOLEVEL;
615 return false;
618 // conditional formatting style names -----------------------------------------
620 const String XclTools::maCFStyleNamePrefix( RTL_CONSTASCII_USTRINGPARAM( "Excel_CondFormat_" ) );
622 String XclTools::GetCondFormatStyleName( SCTAB nScTab, sal_Int32 nFormat, sal_uInt16 nCondition )
624 return String( maCFStyleNamePrefix ).Append( String::CreateFromInt32( nScTab + 1 ) ).
625 Append( '_' ).Append( String::CreateFromInt32( nFormat + 1 ) ).
626 Append( '_' ).Append( String::CreateFromInt32( nCondition + 1 ) );
629 bool XclTools::IsCondFormatStyleName( const String& rStyleName, xub_StrLen* pnNextChar )
631 xub_StrLen nPrefixLen = maCFStyleNamePrefix.Len();
632 if( rStyleName.EqualsIgnoreCaseAscii( maCFStyleNamePrefix, 0, nPrefixLen ) )
634 if( pnNextChar ) *pnNextChar = nPrefixLen;
635 return true;
637 return false;
640 // stream handling ------------------------------------------------------------
642 void XclTools::SkipSubStream( XclImpStream& rStrm )
644 bool bLoop = true;
645 while( bLoop && rStrm.StartNextRecord() )
647 sal_uInt16 nRecId = rStrm.GetRecId();
648 bLoop = nRecId != EXC_ID_EOF;
649 if( (nRecId == EXC_ID2_BOF) || (nRecId == EXC_ID3_BOF) || (nRecId == EXC_ID4_BOF) || (nRecId == EXC_ID5_BOF) )
650 SkipSubStream( rStrm );
654 // read/write colors ----------------------------------------------------------
656 XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor )
658 sal_uInt8 nR, nG, nB, nD;
659 rStrm >> nR >> nG >> nB >> nD;
660 rColor.SetColor( RGB_COLORDATA( nR, nG, nB ) );
661 return rStrm;
664 XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor )
666 return rStrm << rColor.GetRed() << rColor.GetGreen() << rColor.GetBlue() << sal_uInt8( 0 );
669 // ============================================================================