LCOV - code coverage report
Current view: top level - libreoffice/sc/source/filter/excel - xltools.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 162 306 52.9 %
Date: 2012-12-27 Functions: 35 49 71.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10