LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/filter/excel - xistyle.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 749 1059 70.7 %
Date: 2013-07-09 Functions: 88 122 72.1 %
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             : #include "xistyle.hxx"
      21             : #include <sfx2/printer.hxx>
      22             : #include <sfx2/objsh.hxx>
      23             : #include <svtools/ctrltool.hxx>
      24             : #include <editeng/editobj.hxx>
      25             : #include "scitems.hxx"
      26             : #include <editeng/fontitem.hxx>
      27             : #include <editeng/fhgtitem.hxx>
      28             : #include <editeng/wghtitem.hxx>
      29             : #include <editeng/udlnitem.hxx>
      30             : #include <editeng/postitem.hxx>
      31             : #include <editeng/crossedoutitem.hxx>
      32             : #include <editeng/contouritem.hxx>
      33             : #include <editeng/shdditem.hxx>
      34             : #include <editeng/escapementitem.hxx>
      35             : #include <svx/algitem.hxx>
      36             : #include <editeng/boxitem.hxx>
      37             : #include <editeng/lineitem.hxx>
      38             : #include <svx/rotmodit.hxx>
      39             : #include <editeng/colritem.hxx>
      40             : #include <editeng/brushitem.hxx>
      41             : #include <editeng/frmdiritem.hxx>
      42             : #include <editeng/eeitem.hxx>
      43             : #include <editeng/flstitem.hxx>
      44             : #include <editeng/justifyitem.hxx>
      45             : #include <sal/macros.h>
      46             : #include "document.hxx"
      47             : #include "docpool.hxx"
      48             : #include "attrib.hxx"
      49             : #include "stlpool.hxx"
      50             : #include "stlsheet.hxx"
      51             : #include "formulacell.hxx"
      52             : #include "globstr.hrc"
      53             : #include "attarray.hxx"
      54             : #include "xltracer.hxx"
      55             : #include "xistream.hxx"
      56             : #include "xicontent.hxx"
      57             : 
      58             : #include "root.hxx"
      59             : #include "colrowst.hxx"
      60             : #include "svl/poolcach.hxx"
      61             : 
      62             : #include <list>
      63             : 
      64             : using ::std::list;
      65             : 
      66             : #include <cppuhelper/implbase1.hxx>
      67             : #include <com/sun/star/container/XIndexAccess.hpp>
      68             : #include <com/sun/star/beans/XPropertySet.hpp>
      69             : using namespace ::com::sun::star;
      70             : 
      71             : typedef ::cppu::WeakImplHelper1< container::XIndexAccess > XIndexAccess_BASE;
      72             : typedef ::std::vector< ColorData > ColorDataVec;
      73             : 
      74           4 : class PaletteIndex : public XIndexAccess_BASE
      75             : {
      76             : public:
      77           2 :     PaletteIndex( const ColorDataVec& rColorDataTable ) : maColorData( rColorDataTable ) {}
      78             : 
      79             :     // Methods XIndexAccess
      80           0 :     virtual ::sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException)
      81             :     {
      82           0 :          return  maColorData.size();
      83             :     }
      84             : 
      85           0 :     virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
      86             :     {
      87             :         //--Index;  // apparently the palette is already 1 based
      88           0 :         return uno::makeAny( sal_Int32( maColorData[ Index ] ) );
      89             :     }
      90             : 
      91             :     // Methods XElementAcess
      92           0 :     virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException)
      93             :     {
      94           0 :         return ::getCppuType( (sal_Int32*)0 );
      95             :     }
      96           0 :     virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException)
      97             :     {
      98           0 :         return (maColorData.size() > 0);
      99             :     }
     100             : 
     101             : private:
     102             :     ColorDataVec        maColorData;
     103             : };
     104             : 
     105             : void
     106           2 : XclImpPalette::ExportPalette()
     107             : {
     108           2 :     if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
     109             :     {
     110             :         // copy values in color palette
     111           2 :         sal_Int16 nColors =  maColorTable.size();
     112           2 :         ColorDataVec aColors;
     113           2 :         aColors.resize( nColors );
     114         569 :         for( sal_uInt16 nIndex = 0; nIndex < nColors; ++nIndex )
     115         567 :             aColors[ nIndex ] = GetColorData( nIndex );
     116             : 
     117           4 :         uno::Reference< beans::XPropertySet > xProps( pDocShell->GetModel(), uno::UNO_QUERY );
     118           2 :         if ( xProps.is() )
     119             :         {
     120           2 :             uno::Reference< container::XIndexAccess > xIndex( new PaletteIndex( aColors ) );
     121           2 :             xProps->setPropertyValue( "ColorPalette", uno::makeAny( xIndex ) );
     122           2 :         }
     123             :     }
     124             : 
     125           2 : }
     126             : // PALETTE record - color information =========================================
     127             : 
     128          46 : XclImpPalette::XclImpPalette( const XclImpRoot& rRoot ) :
     129          46 :     XclDefaultPalette( rRoot ), mrRoot( rRoot )
     130             : {
     131          46 : }
     132             : 
     133           0 : void XclImpPalette::Initialize()
     134             : {
     135           0 :     maColorTable.clear();
     136           0 : }
     137             : 
     138        8706 : ColorData XclImpPalette::GetColorData( sal_uInt16 nXclIndex ) const
     139             : {
     140        8706 :     if( nXclIndex >= EXC_COLOR_USEROFFSET )
     141             :     {
     142        8690 :         sal_uInt32 nIx = nXclIndex - EXC_COLOR_USEROFFSET;
     143        8690 :         if( nIx < maColorTable.size() )
     144         553 :             return maColorTable[ nIx ];
     145             :     }
     146        8153 :     return GetDefColorData( nXclIndex );
     147             : }
     148             : 
     149           2 : void XclImpPalette::ReadPalette( XclImpStream& rStrm )
     150             : {
     151             :     sal_uInt16 nCount;
     152           2 :     rStrm >> nCount;
     153             :     OSL_ENSURE( rStrm.GetRecLeft() == static_cast< sal_Size >( 4 * nCount ),
     154             :         "XclImpPalette::ReadPalette - size mismatch" );
     155             : 
     156           2 :     maColorTable.resize( nCount );
     157           2 :     Color aColor;
     158         569 :     for( sal_uInt16 nIndex = 0; nIndex < nCount; ++nIndex )
     159             :     {
     160         567 :         rStrm >> aColor;
     161         567 :         maColorTable[ nIndex ] = aColor.GetColor();
     162             :     }
     163           2 :     ExportPalette();
     164           2 : }
     165             : 
     166             : // FONT record - font information =============================================
     167             : 
     168         702 : XclImpFont::XclImpFont( const XclImpRoot& rRoot ) :
     169             :     XclImpRoot( rRoot ),
     170             :     mbHasCharSet( false ),
     171             :     mbHasWstrn( true ),
     172             :     mbHasAsian( false ),
     173         702 :     mbHasCmplx( false )
     174             : {
     175         702 :     SetAllUsedFlags( false );
     176         702 : }
     177             : 
     178          39 : XclImpFont::XclImpFont( const XclImpRoot& rRoot, const XclFontData& rFontData ) :
     179          39 :     XclImpRoot( rRoot )
     180             : {
     181          39 :     SetFontData( rFontData, false );
     182          39 : }
     183             : 
     184        1487 : void XclImpFont::SetAllUsedFlags( bool bUsed )
     185             : {
     186             :     mbFontNameUsed = mbHeightUsed = mbColorUsed = mbWeightUsed = mbEscapemUsed =
     187        1487 :         mbUnderlUsed = mbItalicUsed = mbStrikeUsed = mbOutlineUsed = mbShadowUsed = bUsed;
     188        1487 : }
     189             : 
     190         175 : void XclImpFont::SetFontData( const XclFontData& rFontData, bool bHasCharSet )
     191             : {
     192         175 :     maData = rFontData;
     193         175 :     mbHasCharSet = bHasCharSet;
     194         175 :     if( maData.maStyle.Len() )
     195             :     {
     196           2 :         if( SfxObjectShell* pDocShell = GetDocShell() )
     197             :         {
     198           2 :             if( const SvxFontListItem* pInfoItem = static_cast< const SvxFontListItem* >(
     199           2 :                 pDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) ) )
     200             :             {
     201           2 :                 if( const FontList* pFontList = pInfoItem->GetFontList() )
     202             :                 {
     203           2 :                     FontInfo aFontInfo( pFontList->Get( maData.maName, maData.maStyle ) );
     204           2 :                     maData.SetScWeight( aFontInfo.GetWeight() );
     205           2 :                     maData.SetScPosture( aFontInfo.GetItalic() );
     206             :                 }
     207             :             }
     208             :         }
     209           2 :         maData.maStyle.Erase();
     210             :     }
     211         175 :     GuessScriptType();
     212         175 :     SetAllUsedFlags( true );
     213         175 : }
     214             : 
     215          44 : rtl_TextEncoding XclImpFont::GetFontEncoding() const
     216             : {
     217             :     // #i63105# use text encoding from FONT record
     218             :     // #i67768# BIFF2-BIFF4 FONT records do not contain character set
     219          44 :     rtl_TextEncoding eFontEnc = mbHasCharSet ? maData.GetFontEncoding() : GetTextEncoding();
     220          44 :     return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? GetTextEncoding() : eFontEnc;
     221             : }
     222             : 
     223         610 : void XclImpFont::ReadFont( XclImpStream& rStrm )
     224             : {
     225         610 :     switch( GetBiff() )
     226             :     {
     227             :         case EXC_BIFF2:
     228           0 :             ReadFontData2( rStrm );
     229           0 :             ReadFontName2( rStrm );
     230           0 :         break;
     231             :         case EXC_BIFF3:
     232             :         case EXC_BIFF4:
     233           0 :             ReadFontData2( rStrm );
     234           0 :             ReadFontColor( rStrm );
     235           0 :             ReadFontName2( rStrm );
     236           0 :         break;
     237             :         case EXC_BIFF5:
     238           0 :             ReadFontData5( rStrm );
     239           0 :             ReadFontName2( rStrm );
     240           0 :         break;
     241             :         case EXC_BIFF8:
     242         610 :             ReadFontData5( rStrm );
     243         610 :             ReadFontName8( rStrm );
     244         610 :         break;
     245             :         default:
     246             :             DBG_ERROR_BIFF();
     247         610 :             return;
     248             :     }
     249         610 :     GuessScriptType();
     250         610 :     SetAllUsedFlags( true );
     251             : }
     252             : 
     253           0 : void XclImpFont::ReadEfont( XclImpStream& rStrm )
     254             : {
     255           0 :     ReadFontColor( rStrm );
     256           0 : }
     257             : 
     258           0 : void XclImpFont::ReadCFFontBlock( XclImpStream& rStrm )
     259             : {
     260             :     OSL_ENSURE_BIFF( GetBiff() == EXC_BIFF8 );
     261           0 :     if( GetBiff() != EXC_BIFF8 )
     262           0 :         return;
     263             : 
     264             :     sal_uInt32 nHeight, nStyle, nColor, nFontFlags1, nFontFlags2, nFontFlags3;
     265             :     sal_uInt16 nWeight, nEscapem;
     266             :     sal_uInt8 nUnderl;
     267             : 
     268           0 :     rStrm.Ignore( 64 );
     269           0 :     rStrm >> nHeight >> nStyle >> nWeight >> nEscapem >> nUnderl;
     270           0 :     rStrm.Ignore( 3 );
     271           0 :     rStrm >> nColor;
     272           0 :     rStrm.Ignore( 4 );
     273           0 :     rStrm >> nFontFlags1 >> nFontFlags2 >> nFontFlags3;
     274           0 :     rStrm.Ignore( 18 );
     275             : 
     276           0 :     if( (mbHeightUsed = (nHeight <= 0x7FFF)) == true )
     277           0 :         maData.mnHeight = static_cast< sal_uInt16 >( nHeight );
     278           0 :     if( (mbWeightUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE ) && (nWeight < 0x7FFF)) == true )
     279           0 :         maData.mnWeight = static_cast< sal_uInt16 >( nWeight );
     280           0 :     if( (mbItalicUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STYLE )) == true )
     281           0 :         maData.mbItalic = ::get_flag( nStyle, EXC_CF_FONT_STYLE );
     282           0 :     if( (mbUnderlUsed = !::get_flag( nFontFlags3, EXC_CF_FONT_UNDERL ) && (nUnderl <= 0x7F)) == true )
     283           0 :         maData.mnUnderline = nUnderl;
     284           0 :     if( (mbColorUsed = (nColor <= 0x7FFF)) == true )
     285           0 :         maData.maColor = GetPalette().GetColor( static_cast< sal_uInt16 >( nColor ) );
     286           0 :     if( (mbStrikeUsed = !::get_flag( nFontFlags1, EXC_CF_FONT_STRIKEOUT )) == true )
     287           0 :         maData.mbStrikeout = ::get_flag( nStyle, EXC_CF_FONT_STRIKEOUT );
     288             : }
     289             : 
     290        1301 : void XclImpFont::FillToItemSet( SfxItemSet& rItemSet, XclFontItemType eType, bool bSkipPoolDefs ) const
     291             : {
     292             :     // true = edit engine Which-IDs (EE_CHAR_*); false = Calc Which-IDs (ATTR_*)
     293        1301 :     bool bEE = eType != EXC_FONTITEM_CELL;
     294             : 
     295             : // item = the item to put into the item set
     296             : // sc_which = the Calc Which-ID of the item
     297             : // ee_which = the edit engine Which-ID of the item
     298             : #define PUTITEM( item, sc_which, ee_which ) \
     299             :     ScfTools::PutItem( rItemSet, item, (bEE ? (ee_which) : (sc_which)), bSkipPoolDefs )
     300             : 
     301             : // Font item
     302             :     // #i36997# do not set default Tahoma font from notes
     303        1301 :     bool bDefNoteFont = (eType == EXC_FONTITEM_NOTE) && (maData.maName.EqualsIgnoreCaseAscii( "Tahoma" ));
     304        1301 :     if( mbFontNameUsed && !bDefNoteFont )
     305             :     {
     306        1301 :         rtl_TextEncoding eFontEnc = maData.GetFontEncoding();
     307         141 :         rtl_TextEncoding eTempTextEnc = (bEE && (eFontEnc == GetTextEncoding())) ?
     308        1440 :             ScfTools::GetSystemTextEncoding() : eFontEnc;
     309             : 
     310             :         //add corresponding pitch for FontFamily
     311        1301 :         FontPitch ePitch = PITCH_DONTKNOW;
     312        1301 :         FontFamily eFtFamily = maData.GetScFamily( GetTextEncoding() );
     313        1301 :         switch( eFtFamily ) //refer http://msdn.microsoft.com/en-us/library/aa246306(v=VS.60).aspx
     314             :         {
     315           0 :             case FAMILY_ROMAN:              ePitch = PITCH_VARIABLE;        break;
     316         899 :             case FAMILY_SWISS:              ePitch = PITCH_VARIABLE;        break;
     317          93 :             case FAMILY_MODERN:             ePitch = PITCH_FIXED;           break;
     318         309 :             default:                        break;
     319             :          }
     320        1301 :         SvxFontItem aFontItem( eFtFamily , maData.maName, EMPTY_STRING, ePitch, eTempTextEnc, ATTR_FONT );
     321             : 
     322             :         // set only for valid script types
     323        1301 :         if( mbHasWstrn )
     324        1301 :             PUTITEM( aFontItem, ATTR_FONT,      EE_CHAR_FONTINFO );
     325        1301 :         if( mbHasAsian )
     326           0 :             PUTITEM( aFontItem, ATTR_CJK_FONT,  EE_CHAR_FONTINFO_CJK );
     327        1301 :         if( mbHasCmplx )
     328         960 :             PUTITEM( aFontItem, ATTR_CTL_FONT,  EE_CHAR_FONTINFO_CTL );
     329             :     }
     330             : 
     331             : // Font height (for all script types)
     332        1301 :     if( mbHeightUsed )
     333             :     {
     334        1301 :         sal_Int32 nHeight = maData.mnHeight;
     335        1301 :         if( bEE && (eType != EXC_FONTITEM_HF) )     // do not convert header/footer height
     336         102 :             nHeight = (nHeight * 127 + 36) / EXC_POINTS_PER_INCH;   // 1 in == 72 pt
     337             : 
     338        1301 :         SvxFontHeightItem aHeightItem( nHeight, 100, ATTR_FONT_HEIGHT );
     339        1301 :         PUTITEM( aHeightItem,   ATTR_FONT_HEIGHT,       EE_CHAR_FONTHEIGHT );
     340        1301 :         PUTITEM( aHeightItem,   ATTR_CJK_FONT_HEIGHT,   EE_CHAR_FONTHEIGHT_CJK );
     341        1301 :         PUTITEM( aHeightItem,   ATTR_CTL_FONT_HEIGHT,   EE_CHAR_FONTHEIGHT_CTL );
     342             :     }
     343             : 
     344             : // Font color - pass AUTO_COL to item
     345        1301 :     if( mbColorUsed )
     346        1301 :         PUTITEM( SvxColorItem( maData.maColor, ATTR_FONT_COLOR  ), ATTR_FONT_COLOR, EE_CHAR_COLOR );
     347             : 
     348             : // Font weight (for all script types)
     349        1301 :     if( mbWeightUsed )
     350             :     {
     351        1301 :         SvxWeightItem aWeightItem( maData.GetScWeight(), ATTR_FONT_WEIGHT );
     352        1301 :         PUTITEM( aWeightItem,   ATTR_FONT_WEIGHT,       EE_CHAR_WEIGHT );
     353        1301 :         PUTITEM( aWeightItem,   ATTR_CJK_FONT_WEIGHT,   EE_CHAR_WEIGHT_CJK );
     354        1301 :         PUTITEM( aWeightItem,   ATTR_CTL_FONT_WEIGHT,   EE_CHAR_WEIGHT_CTL );
     355             :     }
     356             : 
     357             : // Font underline
     358        1301 :     if( mbUnderlUsed )
     359             :     {
     360        1301 :         SvxUnderlineItem aUnderlItem( maData.GetScUnderline(), ATTR_FONT_UNDERLINE );
     361        1301 :         PUTITEM( aUnderlItem,   ATTR_FONT_UNDERLINE,    EE_CHAR_UNDERLINE );
     362             :     }
     363             : 
     364             : // Font posture (for all script types)
     365        1301 :     if( mbItalicUsed )
     366             :     {
     367        1301 :         SvxPostureItem aPostItem( maData.GetScPosture(), ATTR_FONT_POSTURE );
     368        1301 :         PUTITEM( aPostItem, ATTR_FONT_POSTURE,      EE_CHAR_ITALIC );
     369        1301 :         PUTITEM( aPostItem, ATTR_CJK_FONT_POSTURE,  EE_CHAR_ITALIC_CJK );
     370        1301 :         PUTITEM( aPostItem, ATTR_CTL_FONT_POSTURE,  EE_CHAR_ITALIC_CTL );
     371             :     }
     372             : 
     373             : // Boolean attributes crossed out, contoured, shadowed
     374        1301 :     if( mbStrikeUsed )
     375        1301 :         PUTITEM( SvxCrossedOutItem( maData.GetScStrikeout(), ATTR_FONT_CROSSEDOUT ), ATTR_FONT_CROSSEDOUT, EE_CHAR_STRIKEOUT );
     376        1301 :     if( mbOutlineUsed )
     377        1301 :         PUTITEM( SvxContourItem( maData.mbOutline, ATTR_FONT_CONTOUR ), ATTR_FONT_CONTOUR, EE_CHAR_OUTLINE );
     378        1301 :     if( mbShadowUsed )
     379        1301 :         PUTITEM( SvxShadowedItem( maData.mbShadow, ATTR_FONT_SHADOWED ), ATTR_FONT_SHADOWED, EE_CHAR_SHADOW );
     380             : 
     381             : // Super-/subscript: only on edit engine objects
     382        1301 :     if( mbEscapemUsed && bEE )
     383         141 :         rItemSet.Put( SvxEscapementItem( maData.GetScEscapement(), EE_CHAR_ESCAPEMENT ) );
     384             : 
     385             : #undef PUTITEM
     386        1301 : }
     387             : 
     388         187 : void XclImpFont::WriteFontProperties( ScfPropertySet& rPropSet,
     389             :         XclFontPropSetType eType, const Color* pFontColor ) const
     390             : {
     391         187 :     GetFontPropSetHelper().WriteFontProperties(
     392         374 :         rPropSet, eType, maData, mbHasWstrn, mbHasAsian, mbHasCmplx, pFontColor );
     393         187 : }
     394             : 
     395           0 : void XclImpFont::ReadFontData2( XclImpStream& rStrm )
     396             : {
     397             :     sal_uInt16 nFlags;
     398           0 :     rStrm >> maData.mnHeight >> nFlags;
     399             : 
     400           0 :     maData.mnWeight     = ::get_flagvalue( nFlags, EXC_FONTATTR_BOLD, EXC_FONTWGHT_BOLD, EXC_FONTWGHT_NORMAL );
     401           0 :     maData.mnUnderline  = ::get_flagvalue( nFlags, EXC_FONTATTR_UNDERLINE, EXC_FONTUNDERL_SINGLE, EXC_FONTUNDERL_NONE );
     402           0 :     maData.mbItalic     = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
     403           0 :     maData.mbStrikeout  = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
     404           0 :     maData.mbOutline    = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
     405           0 :     maData.mbShadow     = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
     406           0 :     mbHasCharSet = false;
     407           0 : }
     408             : 
     409         610 : void XclImpFont::ReadFontData5( XclImpStream& rStrm )
     410             : {
     411             :     sal_uInt16 nFlags;
     412             : 
     413         610 :     rStrm >> maData.mnHeight >> nFlags;
     414         610 :     ReadFontColor( rStrm );
     415         610 :     rStrm >> maData.mnWeight >> maData.mnEscapem >> maData.mnUnderline >> maData.mnFamily >> maData.mnCharSet;
     416         610 :     rStrm.Ignore( 1 );
     417             : 
     418         610 :     maData.mbItalic     = ::get_flag( nFlags, EXC_FONTATTR_ITALIC );
     419         610 :     maData.mbStrikeout  = ::get_flag( nFlags, EXC_FONTATTR_STRIKEOUT );
     420         610 :     maData.mbOutline    = ::get_flag( nFlags, EXC_FONTATTR_OUTLINE );
     421         610 :     maData.mbShadow     = ::get_flag( nFlags, EXC_FONTATTR_SHADOW );
     422         610 :     mbHasCharSet = true;
     423         610 : }
     424             : 
     425         610 : void XclImpFont::ReadFontColor( XclImpStream& rStrm )
     426             : {
     427         610 :     maData.maColor = GetPalette().GetColor( rStrm.ReaduInt16() );
     428         610 : }
     429             : 
     430           0 : void XclImpFont::ReadFontName2( XclImpStream& rStrm )
     431             : {
     432           0 :     maData.maName = rStrm.ReadByteString( false );
     433           0 : }
     434             : 
     435         610 : void XclImpFont::ReadFontName8( XclImpStream& rStrm )
     436             : {
     437         610 :     maData.maName = rStrm.ReadUniString( rStrm.ReaduInt8() );
     438         610 : }
     439             : 
     440         785 : void XclImpFont::GuessScriptType()
     441             : {
     442         785 :     mbHasWstrn = true;
     443         785 :     mbHasAsian = mbHasCmplx = false;
     444             : 
     445             :     // find the script types for which the font contains characters
     446         785 :     if( OutputDevice* pPrinter = GetPrinter() )
     447             :     {
     448         785 :         Font aFont( maData.maName, Size( 0, 10 ) );
     449        1570 :         FontCharMap aCharMap;
     450             : 
     451         785 :         pPrinter->SetFont( aFont );
     452         785 :         if( pPrinter->GetFontCharMap( aCharMap ) )
     453             :         {
     454             :             // CJK fonts
     455             :             mbHasAsian =
     456        1570 :                 aCharMap.HasChar( 0x3041 ) ||   // 3040-309F: Hiragana
     457        1570 :                 aCharMap.HasChar( 0x30A1 ) ||   // 30A0-30FF: Katakana
     458        1570 :                 aCharMap.HasChar( 0x3111 ) ||   // 3100-312F: Bopomofo
     459        1570 :                 aCharMap.HasChar( 0x3131 ) ||   // 3130-318F: Hangul Compatibility Jamo
     460        1570 :                 aCharMap.HasChar( 0x3301 ) ||   // 3300-33FF: CJK Compatibility
     461        1570 :                 aCharMap.HasChar( 0x3401 ) ||   // 3400-4DBF: CJK Unified Ideographs Extension A
     462        1570 :                 aCharMap.HasChar( 0x4E01 ) ||   // 4E00-9FAF: CJK Unified Ideographs
     463        1570 :                 aCharMap.HasChar( 0x7E01 ) ||   // 4E00-9FAF: CJK unified ideographs
     464        1570 :                 aCharMap.HasChar( 0xA001 ) ||   // A001-A48F: Yi Syllables
     465        1570 :                 aCharMap.HasChar( 0xAC01 ) ||   // AC00-D7AF: Hangul Syllables
     466        1570 :                 aCharMap.HasChar( 0xCC01 ) ||   // AC00-D7AF: Hangul Syllables
     467        2355 :                 aCharMap.HasChar( 0xF901 ) ||   // F900-FAFF: CJK Compatibility Ideographs
     468        1570 :                 aCharMap.HasChar( 0xFF71 );     // FF00-FFEF: Halfwidth/Fullwidth Forms
     469             :             // CTL fonts
     470             :             mbHasCmplx =
     471        1160 :                 aCharMap.HasChar( 0x05D1 ) ||   // 0590-05FF: Hebrew
     472         750 :                 aCharMap.HasChar( 0x0631 ) ||   // 0600-06FF: Arabic
     473         750 :                 aCharMap.HasChar( 0x0721 ) ||   // 0700-074F: Syriac
     474         750 :                 aCharMap.HasChar( 0x0911 ) ||   // 0900-0DFF: Indic scripts
     475         750 :                 aCharMap.HasChar( 0x0E01 ) ||   // 0E00-0E7F: Thai
     476         750 :                 aCharMap.HasChar( 0xFB21 ) ||   // FB1D-FB4F: Hebrew Presentation Forms
     477        1535 :                 aCharMap.HasChar( 0xFB51 ) ||   // FB50-FDFF: Arabic Presentation Forms-A
     478        1160 :                 aCharMap.HasChar( 0xFE71 );     // FE70-FEFF: Arabic Presentation Forms-B
     479             :             // Western fonts
     480         785 :             mbHasWstrn = (!mbHasAsian && !mbHasCmplx) || aCharMap.HasChar( 'A' );
     481         785 :         }
     482             :     }
     483         785 : }
     484             : 
     485             : // ----------------------------------------------------------------------------
     486             : 
     487          46 : XclImpFontBuffer::XclImpFontBuffer( const XclImpRoot& rRoot ) :
     488             :     XclImpRoot( rRoot ),
     489             :     maFont4( rRoot ),
     490          46 :     maCtrlFont( rRoot )
     491             : {
     492          46 :     Initialize();
     493             : 
     494             :     // default font for form controls without own font information
     495          46 :     XclFontData aCtrlFontData;
     496          46 :     switch( GetBiff() )
     497             :     {
     498             :         case EXC_BIFF2:
     499             :         case EXC_BIFF3:
     500             :         case EXC_BIFF4:
     501             :         case EXC_BIFF5:
     502           0 :             aCtrlFontData.maName.AssignAscii( "Helv" );
     503           0 :             aCtrlFontData.mnHeight = 160;
     504           0 :             aCtrlFontData.mnWeight = EXC_FONTWGHT_BOLD;
     505           0 :         break;
     506             :         case EXC_BIFF8:
     507          46 :             aCtrlFontData.maName.AssignAscii( "Tahoma" );
     508          46 :             aCtrlFontData.mnHeight = 160;
     509          46 :             aCtrlFontData.mnWeight = EXC_FONTWGHT_NORMAL;
     510          46 :         break;
     511             :         default:
     512             :             DBG_ERROR_BIFF();
     513             :     }
     514          46 :     maCtrlFont.SetFontData( aCtrlFontData, false );
     515          46 : }
     516             : 
     517          46 : void XclImpFontBuffer::Initialize()
     518             : {
     519          46 :     maFontList.clear();
     520             : 
     521             :     // application font for column width calculation, later filled with first font from font list
     522          46 :     XclFontData aAppFontData;
     523          46 :     aAppFontData.maName.AssignAscii( "Arial" );
     524          46 :     aAppFontData.mnHeight = 200;
     525          46 :     aAppFontData.mnWeight = EXC_FONTWGHT_NORMAL;
     526          46 :     UpdateAppFont( aAppFontData, false );
     527          46 : }
     528             : 
     529       13021 : const XclImpFont* XclImpFontBuffer::GetFont( sal_uInt16 nFontIndex ) const
     530             : {
     531             :     /*  Font with index 4 is not stored in an Excel file, but used e.g. by
     532             :         BIFF5 form pushbutton objects. It is the bold default font.
     533             :         This also means that entries above 4 are out by one in the list. */
     534             : 
     535       13021 :     if (nFontIndex == 4)
     536           0 :         return &maFont4;
     537             : 
     538       13021 :     if (nFontIndex < 4)
     539             :     {
     540             :         // Font ID is zero-based when it's less than 4.
     541        9187 :         return nFontIndex >= maFontList.size() ? NULL : &maFontList[nFontIndex];
     542             :     }
     543             : 
     544             :     // Font ID is greater than 4.  It is now 1-based.
     545        3834 :     return nFontIndex > maFontList.size() ? NULL : &maFontList[nFontIndex-1];
     546             : }
     547             : 
     548         610 : void XclImpFontBuffer::ReadFont( XclImpStream& rStrm )
     549             : {
     550         610 :     XclImpFont* pFont = new XclImpFont( GetRoot() );
     551         610 :     pFont->ReadFont( rStrm );
     552         610 :     maFontList.push_back( pFont );
     553             : 
     554         610 :     if( maFontList.size() == 1 )
     555             :     {
     556          44 :         UpdateAppFont( pFont->GetFontData(), pFont->HasCharSet() );
     557             :         // #i71033# set text encoding from application font, if CODEPAGE is missing
     558          44 :         SetAppFontEncoding( pFont->GetFontEncoding() );
     559             :     }
     560         610 : }
     561             : 
     562           0 : void XclImpFontBuffer::ReadEfont( XclImpStream& rStrm )
     563             : {
     564           0 :     if( !maFontList.empty() )
     565           0 :         maFontList.back().ReadEfont( rStrm );
     566           0 : }
     567             : 
     568        1262 : void XclImpFontBuffer::FillToItemSet(
     569             :         SfxItemSet& rItemSet, XclFontItemType eType,
     570             :         sal_uInt16 nFontIdx, bool bSkipPoolDefs ) const
     571             : {
     572        1262 :     if( const XclImpFont* pFont = GetFont( nFontIdx ) )
     573        1262 :         pFont->FillToItemSet( rItemSet, eType, bSkipPoolDefs );
     574        1262 : }
     575             : 
     576         187 : void XclImpFontBuffer::WriteFontProperties( ScfPropertySet& rPropSet,
     577             :         XclFontPropSetType eType, sal_uInt16 nFontIdx, const Color* pFontColor ) const
     578             : {
     579         187 :     if( const XclImpFont* pFont = GetFont( nFontIdx ) )
     580         187 :         pFont->WriteFontProperties( rPropSet, eType, pFontColor );
     581         187 : }
     582             : 
     583           0 : void XclImpFontBuffer::WriteDefaultCtrlFontProperties( ScfPropertySet& rPropSet ) const
     584             : {
     585           0 :     maCtrlFont.WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL );
     586           0 : }
     587             : 
     588          90 : void XclImpFontBuffer::UpdateAppFont( const XclFontData& rFontData, bool bHasCharSet )
     589             : {
     590          90 :     maAppFont = rFontData;
     591             :     // #i3006# Calculate the width of '0' from first font and current printer.
     592          90 :     SetCharWidth( maAppFont );
     593             : 
     594             :     // font 4 is bold font 0
     595          90 :     XclFontData aFont4Data( maAppFont );
     596          90 :     aFont4Data.mnWeight = EXC_FONTWGHT_BOLD;
     597          90 :     maFont4.SetFontData( aFont4Data, bHasCharSet );
     598          90 : }
     599             : 
     600             : // FORMAT record - number formats =============================================
     601             : 
     602          46 : XclImpNumFmtBuffer::XclImpNumFmtBuffer( const XclImpRoot& rRoot ) :
     603             :     XclNumFmtBuffer( rRoot ),
     604             :     XclImpRoot( rRoot ),
     605          46 :     mnNextXclIdx( 0 )
     606             : {
     607          46 : }
     608             : 
     609           0 : void XclImpNumFmtBuffer::Initialize()
     610             : {
     611           0 :     maIndexMap.clear();
     612           0 :     mnNextXclIdx = 0;
     613           0 :     InitializeImport();     // base class
     614           0 : }
     615             : 
     616         692 : void XclImpNumFmtBuffer::ReadFormat( XclImpStream& rStrm )
     617             : {
     618         692 :     String aFormat;
     619         692 :     switch( GetBiff() )
     620             :     {
     621             :         case EXC_BIFF2:
     622             :         case EXC_BIFF3:
     623           0 :             aFormat = rStrm.ReadByteString( false );
     624           0 :         break;
     625             : 
     626             :         case EXC_BIFF4:
     627           0 :             rStrm.Ignore( 2 );  // in BIFF4 the index field exists, but is undefined
     628           0 :             aFormat = rStrm.ReadByteString( false );
     629           0 :         break;
     630             : 
     631             :         case EXC_BIFF5:
     632           0 :             rStrm >> mnNextXclIdx;
     633           0 :             aFormat = rStrm.ReadByteString( false );
     634           0 :         break;
     635             : 
     636             :         case EXC_BIFF8:
     637         692 :             rStrm >> mnNextXclIdx;
     638         692 :             aFormat = rStrm.ReadUniString();
     639         692 :         break;
     640             : 
     641             :         default:
     642             :             DBG_ERROR_BIFF();
     643         692 :             return;
     644             :     }
     645             : 
     646         692 :     if( mnNextXclIdx < 0xFFFF )
     647             :     {
     648         692 :         InsertFormat( mnNextXclIdx, aFormat );
     649         692 :         ++mnNextXclIdx;
     650         692 :     }
     651             : }
     652             : 
     653          45 : void XclImpNumFmtBuffer::CreateScFormats()
     654             : {
     655             :     OSL_ENSURE( maIndexMap.empty(), "XclImpNumFmtBuffer::CreateScFormats - already created" );
     656             : 
     657          45 :     SvNumberFormatter& rFormatter = GetFormatter();
     658        4059 :     for( XclNumFmtMap::const_iterator aIt = GetFormatMap().begin(), aEnd = GetFormatMap().end(); aIt != aEnd; ++aIt )
     659             :     {
     660        4014 :         const XclNumFmt& rNumFmt = aIt->second;
     661             : 
     662             :         // insert/convert the Excel number format
     663             :         sal_Int32 nCheckPos;
     664        4014 :         short nType = NUMBERFORMAT_DEFINED;
     665             :         sal_uInt32 nKey;
     666        4014 :         if( rNumFmt.maFormat.Len() )
     667             :         {
     668        2987 :             OUString aFormat( rNumFmt.maFormat );
     669             :             rFormatter.PutandConvertEntry( aFormat, nCheckPos,
     670        2987 :                                            nType, nKey, LANGUAGE_ENGLISH_US, rNumFmt.meLanguage );
     671             :         }
     672             :         else
     673        1027 :             nKey = rFormatter.GetFormatIndex( rNumFmt.meOffset, rNumFmt.meLanguage );
     674             : 
     675             :         // insert the resulting format key into the Excel->Calc index map
     676        4014 :         maIndexMap[ aIt->first ] = nKey;
     677             :     }
     678          45 : }
     679             : 
     680         688 : sal_uLong XclImpNumFmtBuffer::GetScFormat( sal_uInt16 nXclNumFmt ) const
     681             : {
     682         688 :     XclImpIndexMap::const_iterator aIt = maIndexMap.find( nXclNumFmt );
     683         688 :     return (aIt != maIndexMap.end()) ? aIt->second : NUMBERFORMAT_ENTRY_NOT_FOUND;
     684             : }
     685             : 
     686         608 : void XclImpNumFmtBuffer::FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nXclNumFmt, bool bSkipPoolDefs ) const
     687             : {
     688         608 :     sal_uLong nScNumFmt = GetScFormat( nXclNumFmt );
     689         608 :     if( nScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND )
     690           0 :         nScNumFmt = GetStdScNumFmt();
     691         608 :     FillScFmtToItemSet( rItemSet, nScNumFmt, bSkipPoolDefs );
     692         608 : }
     693             : 
     694         608 : void XclImpNumFmtBuffer::FillScFmtToItemSet( SfxItemSet& rItemSet, sal_uLong nScNumFmt, bool bSkipPoolDefs ) const
     695             : {
     696             :     OSL_ENSURE( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND, "XclImpNumFmtBuffer::FillScFmtToItemSet - invalid number format" );
     697         608 :     ScfTools::PutItem( rItemSet, SfxUInt32Item( ATTR_VALUE_FORMAT, nScNumFmt ), bSkipPoolDefs );
     698         608 :     if( rItemSet.GetItemState( ATTR_VALUE_FORMAT, false ) == SFX_ITEM_SET )
     699         571 :         ScGlobal::AddLanguage( rItemSet, GetFormatter() );
     700         608 : }
     701             : 
     702             : // XF, STYLE record - Cell formatting =========================================
     703             : 
     704           0 : void XclImpCellProt::FillFromXF2( sal_uInt8 nNumFmt )
     705             : {
     706           0 :     mbLocked = ::get_flag( nNumFmt, EXC_XF2_LOCKED );
     707           0 :     mbHidden = ::get_flag( nNumFmt, EXC_XF2_HIDDEN );
     708           0 : }
     709             : 
     710        2759 : void XclImpCellProt::FillFromXF3( sal_uInt16 nProt )
     711             : {
     712        2759 :     mbLocked = ::get_flag( nProt, EXC_XF_LOCKED );
     713        2759 :     mbHidden = ::get_flag( nProt, EXC_XF_HIDDEN );
     714        2759 : }
     715             : 
     716          87 : void XclImpCellProt::FillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
     717             : {
     718          87 :     ScfTools::PutItem( rItemSet, ScProtectionAttr( mbLocked, mbHidden ), bSkipPoolDefs );
     719          87 : }
     720             : 
     721             : 
     722             : // ----------------------------------------------------------------------------
     723             : 
     724           0 : void XclImpCellAlign::FillFromXF2( sal_uInt8 nFlags )
     725             : {
     726           0 :     mnHorAlign = ::extract_value< sal_uInt8 >( nFlags, 0, 3 );
     727           0 : }
     728             : 
     729           0 : void XclImpCellAlign::FillFromXF3( sal_uInt16 nAlign )
     730             : {
     731           0 :     mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
     732           0 :     mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );   // new in BIFF3
     733           0 : }
     734             : 
     735           0 : void XclImpCellAlign::FillFromXF4( sal_uInt16 nAlign )
     736             : {
     737           0 :     FillFromXF3( nAlign );
     738           0 :     mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 2 );  // new in BIFF4
     739           0 :     mnOrient = ::extract_value< sal_uInt8 >( nAlign, 6, 2 );    // new in BIFF4
     740           0 : }
     741             : 
     742           0 : void XclImpCellAlign::FillFromXF5( sal_uInt16 nAlign )
     743             : {
     744           0 :     mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
     745           0 :     mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
     746           0 :     mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
     747           0 :     mnOrient = ::extract_value< sal_uInt8 >( nAlign, 8, 2 );
     748           0 : }
     749             : 
     750        2759 : void XclImpCellAlign::FillFromXF8( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib )
     751             : {
     752        2759 :     mnHorAlign = ::extract_value< sal_uInt8 >( nAlign, 0, 3 );
     753        2759 :     mnVerAlign = ::extract_value< sal_uInt8 >( nAlign, 4, 3 );
     754        2759 :     mbLineBreak = ::get_flag( nAlign, EXC_XF_LINEBREAK );
     755        2759 :     mnRotation = ::extract_value< sal_uInt8 >( nAlign, 8, 8 );      // new in BIFF8
     756        2759 :     mnIndent = ::extract_value< sal_uInt8 >( nMiscAttrib, 0, 4 );   // new in BIFF8
     757        2759 :     mbShrink = ::get_flag( nMiscAttrib, EXC_XF8_SHRINK );           // new in BIFF8
     758        2759 :     mnTextDir = ::extract_value< sal_uInt8 >( nMiscAttrib, 6, 2 );  // new in BIFF8
     759        2759 : }
     760             : 
     761         903 : void XclImpCellAlign::FillToItemSet( SfxItemSet& rItemSet, const XclImpFont* pFont, bool bSkipPoolDefs ) const
     762             : {
     763             :     // horizontal alignment
     764         903 :     ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
     765         903 :     ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( GetScHorJustifyMethod(), ATTR_HOR_JUSTIFY_METHOD ), bSkipPoolDefs );
     766             : 
     767             :     // text wrap (#i74508# always if vertical alignment is justified or distributed)
     768         903 :     bool bLineBreak = mbLineBreak || (mnVerAlign == EXC_XF_VER_JUSTIFY) || (mnVerAlign == EXC_XF_VER_DISTRIB);
     769         903 :     ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, bLineBreak ), bSkipPoolDefs );
     770             : 
     771             :     // vertical alignment
     772         903 :     ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
     773         903 :     ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( GetScVerJustifyMethod(), ATTR_VER_JUSTIFY_METHOD ), bSkipPoolDefs );
     774             : 
     775             :     // indent
     776         903 :     sal_uInt16 nScIndent = mnIndent * 200; // 1 Excel unit == 10 pt == 200 twips
     777         903 :     ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, nScIndent ), bSkipPoolDefs );
     778             : 
     779             :     // shrink to fit
     780         903 :     ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, mbShrink ), bSkipPoolDefs );
     781             : 
     782             :     // text orientation/rotation (BIFF2-BIFF7 sets mnOrient)
     783         903 :     sal_uInt8 nXclRot = (mnOrient == EXC_ORIENT_NONE) ? mnRotation : XclTools::GetXclRotFromOrient( mnOrient );
     784         903 :     bool bStacked = (nXclRot == EXC_ROT_STACKED);
     785         903 :     ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, bStacked ), bSkipPoolDefs );
     786             :     // set an angle in the range from -90 to 90 degrees
     787         903 :     sal_Int32 nAngle = XclTools::GetScRotation( nXclRot, 0 );
     788         903 :     ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, nAngle ), bSkipPoolDefs );
     789             :     // set "Use asian vertical layout", if cell is stacked and font contains CKJ characters
     790         903 :     bool bAsianVert = bStacked && pFont && pFont->HasAsianChars();
     791         903 :     ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_VERTICAL_ASIAN, bAsianVert ), bSkipPoolDefs );
     792             : 
     793             :     // CTL text direction
     794         903 :     ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
     795         903 : }
     796             : 
     797             : // ----------------------------------------------------------------------------
     798             : 
     799        2759 : XclImpCellBorder::XclImpCellBorder()
     800             : {
     801        2759 :     SetUsedFlags( false, false );
     802        2759 : }
     803             : 
     804        5518 : void XclImpCellBorder::SetUsedFlags( bool bOuterUsed, bool bDiagUsed )
     805             : {
     806        5518 :     mbLeftUsed = mbRightUsed = mbTopUsed = mbBottomUsed = bOuterUsed;
     807        5518 :     mbDiagUsed = bDiagUsed;
     808        5518 : }
     809             : 
     810           0 : void XclImpCellBorder::FillFromXF2( sal_uInt8 nFlags )
     811             : {
     812           0 :     mnLeftLine   = ::get_flagvalue( nFlags, EXC_XF2_LEFTLINE,   EXC_LINE_THIN, EXC_LINE_NONE );
     813           0 :     mnRightLine  = ::get_flagvalue( nFlags, EXC_XF2_RIGHTLINE,  EXC_LINE_THIN, EXC_LINE_NONE );
     814           0 :     mnTopLine    = ::get_flagvalue( nFlags, EXC_XF2_TOPLINE,    EXC_LINE_THIN, EXC_LINE_NONE );
     815           0 :     mnBottomLine = ::get_flagvalue( nFlags, EXC_XF2_BOTTOMLINE, EXC_LINE_THIN, EXC_LINE_NONE );
     816           0 :     mnLeftColor = mnRightColor = mnTopColor = mnBottomColor = EXC_COLOR_BIFF2_BLACK;
     817           0 :     SetUsedFlags( true, false );
     818           0 : }
     819             : 
     820           0 : void XclImpCellBorder::FillFromXF3( sal_uInt32 nBorder )
     821             : {
     822           0 :     mnTopLine     = ::extract_value< sal_uInt8  >( nBorder,  0, 3 );
     823           0 :     mnLeftLine    = ::extract_value< sal_uInt8  >( nBorder,  8, 3 );
     824           0 :     mnBottomLine  = ::extract_value< sal_uInt8  >( nBorder, 16, 3 );
     825           0 :     mnRightLine   = ::extract_value< sal_uInt8  >( nBorder, 24, 3 );
     826           0 :     mnTopColor    = ::extract_value< sal_uInt16 >( nBorder,  3, 5 );
     827           0 :     mnLeftColor   = ::extract_value< sal_uInt16 >( nBorder, 11, 5 );
     828           0 :     mnBottomColor = ::extract_value< sal_uInt16 >( nBorder, 19, 5 );
     829           0 :     mnRightColor  = ::extract_value< sal_uInt16 >( nBorder, 27, 5 );
     830           0 :     SetUsedFlags( true, false );
     831           0 : }
     832             : 
     833           0 : void XclImpCellBorder::FillFromXF5( sal_uInt32 nBorder, sal_uInt32 nArea )
     834             : {
     835           0 :     mnTopLine     = ::extract_value< sal_uInt8  >( nBorder,  0, 3 );
     836           0 :     mnLeftLine    = ::extract_value< sal_uInt8  >( nBorder,  3, 3 );
     837           0 :     mnBottomLine  = ::extract_value< sal_uInt8  >( nArea,   22, 3 );
     838           0 :     mnRightLine   = ::extract_value< sal_uInt8  >( nBorder,  6, 3 );
     839           0 :     mnTopColor    = ::extract_value< sal_uInt16 >( nBorder,  9, 7 );
     840           0 :     mnLeftColor   = ::extract_value< sal_uInt16 >( nBorder, 16, 7 );
     841           0 :     mnBottomColor = ::extract_value< sal_uInt16 >( nArea,   25, 7 );
     842           0 :     mnRightColor  = ::extract_value< sal_uInt16 >( nBorder, 23, 7 );
     843           0 :     SetUsedFlags( true, false );
     844           0 : }
     845             : 
     846        2759 : void XclImpCellBorder::FillFromXF8( sal_uInt32 nBorder1, sal_uInt32 nBorder2 )
     847             : {
     848        2759 :     mnLeftLine    = ::extract_value< sal_uInt8  >( nBorder1,  0, 4 );
     849        2759 :     mnRightLine   = ::extract_value< sal_uInt8  >( nBorder1,  4, 4 );
     850        2759 :     mnTopLine     = ::extract_value< sal_uInt8  >( nBorder1,  8, 4 );
     851        2759 :     mnBottomLine  = ::extract_value< sal_uInt8  >( nBorder1, 12, 4 );
     852        2759 :     mnLeftColor   = ::extract_value< sal_uInt16 >( nBorder1, 16, 7 );
     853        2759 :     mnRightColor  = ::extract_value< sal_uInt16 >( nBorder1, 23, 7 );
     854        2759 :     mnTopColor    = ::extract_value< sal_uInt16 >( nBorder2,  0, 7 );
     855        2759 :     mnBottomColor = ::extract_value< sal_uInt16 >( nBorder2,  7, 7 );
     856        2759 :     mbDiagTLtoBR  = ::get_flag( nBorder1, EXC_XF_DIAGONAL_TL_TO_BR );
     857        2759 :     mbDiagBLtoTR  = ::get_flag( nBorder1, EXC_XF_DIAGONAL_BL_TO_TR );
     858        2759 :     if( mbDiagTLtoBR || mbDiagBLtoTR )
     859             :     {
     860           0 :         mnDiagLine  = ::extract_value< sal_uInt8 >( nBorder2, 21, 4 );
     861           0 :         mnDiagColor = ::extract_value< sal_uInt16 >( nBorder2, 14, 7 );
     862             :     }
     863        2759 :     SetUsedFlags( true, true );
     864        2759 : }
     865             : 
     866           0 : void XclImpCellBorder::FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor, sal_uInt32 nFlags )
     867             : {
     868           0 :     mnLeftLine    = ::extract_value< sal_uInt8  >( nLineStyle,  0, 4 );
     869           0 :     mnRightLine   = ::extract_value< sal_uInt8  >( nLineStyle,  4, 4 );
     870           0 :     mnTopLine     = ::extract_value< sal_uInt8  >( nLineStyle,  8, 4 );
     871           0 :     mnBottomLine  = ::extract_value< sal_uInt8  >( nLineStyle, 12, 4 );
     872           0 :     mnLeftColor   = ::extract_value< sal_uInt16 >( nLineColor,  0, 7 );
     873           0 :     mnRightColor  = ::extract_value< sal_uInt16 >( nLineColor,  7, 7 );
     874           0 :     mnTopColor    = ::extract_value< sal_uInt16 >( nLineColor, 16, 7 );
     875           0 :     mnBottomColor = ::extract_value< sal_uInt16 >( nLineColor, 23, 7 );
     876           0 :     mbLeftUsed    = !::get_flag( nFlags, EXC_CF_BORDER_LEFT );
     877           0 :     mbRightUsed   = !::get_flag( nFlags, EXC_CF_BORDER_RIGHT );
     878           0 :     mbTopUsed     = !::get_flag( nFlags, EXC_CF_BORDER_TOP );
     879           0 :     mbBottomUsed  = !::get_flag( nFlags, EXC_CF_BORDER_BOTTOM );
     880           0 :     mbDiagUsed    = false;
     881           0 : }
     882             : 
     883           3 : bool XclImpCellBorder::HasAnyOuterBorder() const
     884             : {
     885             :     return
     886           3 :         (mbLeftUsed   && (mnLeftLine != EXC_LINE_NONE)) ||
     887           0 :         (mbRightUsed  && (mnRightLine != EXC_LINE_NONE)) ||
     888           6 :         (mbTopUsed    && (mnTopLine != EXC_LINE_NONE)) ||
     889           3 :         (mbBottomUsed && (mnBottomLine != EXC_LINE_NONE));
     890             : }
     891             : 
     892             : namespace {
     893             : 
     894             : /** Converts the passed line style to a ::editeng::SvxBorderLine, or returns false, if style is "no line". */
     895        5680 : bool lclConvertBorderLine( ::editeng::SvxBorderLine& rLine, const XclImpPalette& rPalette, sal_uInt8 nXclLine, sal_uInt16 nXclColor )
     896             : {
     897             :     static const sal_uInt16 ppnLineParam[][ 4 ] =
     898             :     {
     899             :         //  outer width,        type
     900             :         {   0,                  table::BorderLineStyle::SOLID },  // 0 = none
     901             :         {   EXC_BORDER_THIN,    table::BorderLineStyle::SOLID },  // 1 = thin
     902             :         {   EXC_BORDER_MEDIUM,  table::BorderLineStyle::SOLID },  // 2 = medium
     903             :         {   EXC_BORDER_THIN,    table::BorderLineStyle::DASHED }, // 3 = dashed
     904             :         {   EXC_BORDER_THIN,    table::BorderLineStyle::DOTTED }, // 4 = dotted
     905             :         {   EXC_BORDER_THICK,   table::BorderLineStyle::SOLID },  // 5 = thick
     906             :         {   EXC_BORDER_THIN,    table::BorderLineStyle::DOUBLE }, // 6 = double
     907             :         {   EXC_BORDER_HAIR,    table::BorderLineStyle::FINE_DASHED },  // 7 = hair
     908             :         {   EXC_BORDER_MEDIUM,  table::BorderLineStyle::DASHED }, // 8 = med dash
     909             :         {   EXC_BORDER_THIN,    table::BorderLineStyle::SOLID },  // 9 = thin dashdot
     910             :         {   EXC_BORDER_MEDIUM,  table::BorderLineStyle::SOLID },  // A = med dashdot
     911             :         {   EXC_BORDER_THIN,    table::BorderLineStyle::SOLID },  // B = thin dashdotdot
     912             :         {   EXC_BORDER_MEDIUM,  table::BorderLineStyle::SOLID },  // C = med dashdotdot
     913             :         {   EXC_BORDER_MEDIUM,  table::BorderLineStyle::SOLID }   // D = med slant dashdot
     914             :     };
     915             : 
     916        5680 :     if( nXclLine == EXC_LINE_NONE )
     917        1916 :         return false;
     918        3764 :     if( nXclLine >= SAL_N_ELEMENTS( ppnLineParam ) )
     919           0 :         nXclLine = EXC_LINE_THIN;
     920             : 
     921        3764 :     rLine.SetColor( rPalette.GetColor( nXclColor ) );
     922        3764 :     rLine.SetWidth( ppnLineParam[ nXclLine ][ 0 ] );
     923             :     rLine.SetBorderLineStyle( static_cast< ::editeng::SvxBorderStyle>(
     924        3764 :                 ppnLineParam[ nXclLine ][ 1 ]) );
     925        3764 :     return true;
     926             : }
     927             : 
     928             : } // namespace
     929             : 
     930        1136 : void XclImpCellBorder::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
     931             : {
     932        1136 :     if( mbLeftUsed || mbRightUsed || mbTopUsed || mbBottomUsed )
     933             :     {
     934        1136 :         SvxBoxItem aBoxItem( ATTR_BORDER );
     935        1136 :         ::editeng::SvxBorderLine aLine;
     936        1136 :         if( mbLeftUsed && lclConvertBorderLine( aLine, rPalette, mnLeftLine, mnLeftColor ) )
     937         887 :             aBoxItem.SetLine( &aLine, BOX_LINE_LEFT );
     938        1136 :         if( mbRightUsed && lclConvertBorderLine( aLine, rPalette, mnRightLine, mnRightColor ) )
     939         902 :             aBoxItem.SetLine( &aLine, BOX_LINE_RIGHT );
     940        1136 :         if( mbTopUsed && lclConvertBorderLine( aLine, rPalette, mnTopLine, mnTopColor ) )
     941         975 :             aBoxItem.SetLine( &aLine, BOX_LINE_TOP );
     942        1136 :         if( mbBottomUsed && lclConvertBorderLine( aLine, rPalette, mnBottomLine, mnBottomColor ) )
     943        1000 :             aBoxItem.SetLine( &aLine, BOX_LINE_BOTTOM );
     944        1136 :         ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
     945             :     }
     946        1136 :     if( mbDiagUsed )
     947             :     {
     948        1136 :         SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
     949        2272 :         SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
     950        1136 :         ::editeng::SvxBorderLine aLine;
     951        1136 :         if( lclConvertBorderLine( aLine, rPalette, mnDiagLine, mnDiagColor ) )
     952             :         {
     953           0 :             if( mbDiagTLtoBR )
     954           0 :                 aTLBRItem.SetLine( &aLine );
     955           0 :             if( mbDiagBLtoTR )
     956           0 :                 aBLTRItem.SetLine( &aLine );
     957             :         }
     958        1136 :         ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
     959        2272 :         ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
     960             :     }
     961        1136 : }
     962             : 
     963             : // ----------------------------------------------------------------------------
     964             : 
     965        2759 : XclImpCellArea::XclImpCellArea()
     966             : {
     967        2759 :     SetUsedFlags( false );
     968        2759 : }
     969             : 
     970        5518 : void XclImpCellArea::SetUsedFlags( bool bUsed )
     971             : {
     972        5518 :     mbForeUsed = mbBackUsed = mbPattUsed = bUsed;
     973        5518 : }
     974             : 
     975           0 : void XclImpCellArea::FillFromXF2( sal_uInt8 nFlags )
     976             : {
     977           0 :     mnPattern = ::get_flagvalue( nFlags, EXC_XF2_BACKGROUND, EXC_PATT_12_5_PERC, EXC_PATT_NONE );
     978           0 :     mnForeColor = EXC_COLOR_BIFF2_BLACK;
     979           0 :     mnBackColor = EXC_COLOR_BIFF2_WHITE;
     980           0 :     SetUsedFlags( true );
     981           0 : }
     982             : 
     983           0 : void XclImpCellArea::FillFromXF3( sal_uInt16 nArea )
     984             : {
     985           0 :     mnPattern   = ::extract_value< sal_uInt8  >( nArea,  0, 6 );
     986           0 :     mnForeColor = ::extract_value< sal_uInt16 >( nArea,  6, 5 );
     987           0 :     mnBackColor = ::extract_value< sal_uInt16 >( nArea, 11, 5 );
     988           0 :     SetUsedFlags( true );
     989           0 : }
     990             : 
     991           0 : void XclImpCellArea::FillFromXF5( sal_uInt32 nArea )
     992             : {
     993           0 :     mnPattern   = ::extract_value< sal_uInt8  >( nArea, 16, 6 );
     994           0 :     mnForeColor = ::extract_value< sal_uInt16 >( nArea,  0, 7 );
     995           0 :     mnBackColor = ::extract_value< sal_uInt16 >( nArea,  7, 7 );
     996           0 :     SetUsedFlags( true );
     997           0 : }
     998             : 
     999        2759 : void XclImpCellArea::FillFromXF8( sal_uInt32 nBorder2, sal_uInt16 nArea )
    1000             : {
    1001        2759 :     mnPattern   = ::extract_value< sal_uInt8  >( nBorder2, 26, 6 );
    1002        2759 :     mnForeColor = ::extract_value< sal_uInt16 >( nArea,     0, 7 );
    1003        2759 :     mnBackColor = ::extract_value< sal_uInt16 >( nArea,     7, 7 );
    1004        2759 :     SetUsedFlags( true );
    1005        2759 : }
    1006             : 
    1007           0 : void XclImpCellArea::FillFromCF8( sal_uInt16 nPattern, sal_uInt16 nColor, sal_uInt32 nFlags )
    1008             : {
    1009           0 :     mnForeColor = ::extract_value< sal_uInt16 >( nColor,    0, 7 );
    1010           0 :     mnBackColor = ::extract_value< sal_uInt16 >( nColor,    7, 7 );
    1011           0 :     mnPattern   = ::extract_value< sal_uInt8  >( nPattern, 10, 6 );
    1012           0 :     mbForeUsed  = !::get_flag( nFlags, EXC_CF_AREA_FGCOLOR );
    1013           0 :     mbBackUsed  = !::get_flag( nFlags, EXC_CF_AREA_BGCOLOR );
    1014           0 :     mbPattUsed  = !::get_flag( nFlags, EXC_CF_AREA_PATTERN );
    1015             : 
    1016           0 :     if( mbBackUsed && (!mbPattUsed || (mnPattern == EXC_PATT_SOLID)) )
    1017             :     {
    1018           0 :         mnForeColor = mnBackColor;
    1019           0 :         mnPattern = EXC_PATT_SOLID;
    1020           0 :         mbForeUsed = mbPattUsed = true;
    1021             :     }
    1022           0 :     else if( !mbBackUsed && mbPattUsed && (mnPattern == EXC_PATT_SOLID) )
    1023             :     {
    1024           0 :         mbPattUsed = false;
    1025             :     }
    1026           0 : }
    1027             : 
    1028        1270 : void XclImpCellArea::FillToItemSet( SfxItemSet& rItemSet, const XclImpPalette& rPalette, bool bSkipPoolDefs ) const
    1029             : {
    1030        1270 :     if( mbPattUsed )    // colors may be both unused in cond. formats
    1031             :     {
    1032        1270 :         SvxBrushItem aBrushItem( ATTR_BACKGROUND );
    1033             : 
    1034             :         // do not use IsTransparent() - old Calc filter writes tranparency with different color indexes
    1035        1270 :         if( mnPattern == EXC_PATT_NONE )
    1036             :         {
    1037          85 :             aBrushItem.SetColor( Color( COL_TRANSPARENT ) );
    1038             :         }
    1039             :         else
    1040             :         {
    1041        1185 :             Color aFore( rPalette.GetColor( mbForeUsed ? mnForeColor : EXC_COLOR_WINDOWTEXT ) );
    1042        1185 :             Color aBack( rPalette.GetColor( mbBackUsed ? mnBackColor : EXC_COLOR_WINDOWBACK ) );
    1043        1185 :             aBrushItem.SetColor( XclTools::GetPatternColor( aFore, aBack, mnPattern ) );
    1044             :         }
    1045             : 
    1046        1270 :         ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
    1047             :     }
    1048        1270 : }
    1049             : 
    1050             : 
    1051             : // ----------------------------------------------------------------------------
    1052             : 
    1053        2759 : XclImpXF::XclImpXF( const XclImpRoot& rRoot ) :
    1054             :     XclXFBase( true ),      // default is cell XF
    1055             :     XclImpRoot( rRoot ),
    1056             :     mpStyleSheet( 0 ),
    1057             :     mnXclNumFmt( 0 ),
    1058        2759 :     mnXclFont( 0 )
    1059             : {
    1060        2759 : }
    1061             : 
    1062        5518 : XclImpXF::~XclImpXF()
    1063             : {
    1064        5518 : }
    1065             : 
    1066           0 : void XclImpXF::ReadXF2( XclImpStream& rStrm )
    1067             : {
    1068             :     sal_uInt8 nReadFont, nReadNumFmt, nFlags;
    1069           0 :     rStrm >> nReadFont;
    1070           0 :     rStrm.Ignore( 1 );
    1071           0 :     rStrm >> nReadNumFmt >> nFlags;
    1072             : 
    1073             :     // XF type always cell, no parent, used flags always true
    1074           0 :     SetAllUsedFlags( true );
    1075             : 
    1076             :     // attributes
    1077           0 :     maProtection.FillFromXF2( nReadNumFmt );
    1078           0 :     mnXclFont = nReadFont;
    1079           0 :     mnXclNumFmt = nReadNumFmt & EXC_XF2_VALFMT_MASK;
    1080           0 :     maAlignment.FillFromXF2( nFlags );
    1081           0 :     maBorder.FillFromXF2( nFlags );
    1082           0 :     maArea.FillFromXF2( nFlags );
    1083           0 : }
    1084             : 
    1085           0 : void XclImpXF::ReadXF3( XclImpStream& rStrm )
    1086             : {
    1087             :     sal_uInt32 nBorder;
    1088             :     sal_uInt16 nTypeProt, nAlign, nArea;
    1089             :     sal_uInt8 nReadFont, nReadNumFmt;
    1090           0 :     rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
    1091             : 
    1092             :     // XF type/parent, attribute used flags
    1093           0 :     mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );          // new in BIFF3
    1094           0 :     mnParent = ::extract_value< sal_uInt16 >( nAlign, 4, 12 );  // new in BIFF3
    1095           0 :     SetUsedFlags( ::extract_value< sal_uInt8 >( nTypeProt, 10, 6 ) );
    1096             : 
    1097             :     // attributes
    1098           0 :     maProtection.FillFromXF3( nTypeProt );
    1099           0 :     mnXclFont = nReadFont;
    1100           0 :     mnXclNumFmt = nReadNumFmt;
    1101           0 :     maAlignment.FillFromXF3( nAlign );
    1102           0 :     maBorder.FillFromXF3( nBorder );
    1103           0 :     maArea.FillFromXF3( nArea );                        // new in BIFF3
    1104           0 : }
    1105             : 
    1106           0 : void XclImpXF::ReadXF4( XclImpStream& rStrm )
    1107             : {
    1108             :     sal_uInt32 nBorder;
    1109             :     sal_uInt16 nTypeProt, nAlign, nArea;
    1110             :     sal_uInt8 nReadFont, nReadNumFmt;
    1111           0 :     rStrm >> nReadFont >> nReadNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
    1112             : 
    1113             :     // XF type/parent, attribute used flags
    1114           0 :     mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
    1115           0 :     mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
    1116           0 :     SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
    1117             : 
    1118             :     // attributes
    1119           0 :     maProtection.FillFromXF3( nTypeProt );
    1120           0 :     mnXclFont = nReadFont;
    1121           0 :     mnXclNumFmt = nReadNumFmt;
    1122           0 :     maAlignment.FillFromXF4( nAlign );
    1123           0 :     maBorder.FillFromXF3( nBorder );
    1124           0 :     maArea.FillFromXF3( nArea );
    1125           0 : }
    1126             : 
    1127           0 : void XclImpXF::ReadXF5( XclImpStream& rStrm )
    1128             : {
    1129             :     sal_uInt32 nArea, nBorder;
    1130             :     sal_uInt16 nTypeProt, nAlign;
    1131           0 :     rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nArea >> nBorder;
    1132             : 
    1133             :     // XF type/parent, attribute used flags
    1134           0 :     mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
    1135           0 :     mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
    1136           0 :     SetUsedFlags( ::extract_value< sal_uInt8 >( nAlign, 10, 6 ) );
    1137             : 
    1138             :     // attributes
    1139           0 :     maProtection.FillFromXF3( nTypeProt );
    1140           0 :     maAlignment.FillFromXF5( nAlign );
    1141           0 :     maBorder.FillFromXF5( nBorder, nArea );
    1142           0 :     maArea.FillFromXF5( nArea );
    1143           0 : }
    1144             : 
    1145        2759 : void XclImpXF::ReadXF8( XclImpStream& rStrm )
    1146             : {
    1147             :     sal_uInt32 nBorder1, nBorder2;
    1148             :     sal_uInt16 nTypeProt, nAlign, nMiscAttrib, nArea;
    1149        2759 :     rStrm >> mnXclFont >> mnXclNumFmt >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea;
    1150             : 
    1151             :     // XF type/parent, attribute used flags
    1152        2759 :     mbCellXF = !::get_flag( nTypeProt, EXC_XF_STYLE );
    1153        2759 :     mnParent = ::extract_value< sal_uInt16 >( nTypeProt, 4, 12 );
    1154        2759 :     SetUsedFlags( ::extract_value< sal_uInt8 >( nMiscAttrib, 10, 6 ) );
    1155             : 
    1156             :     // attributes
    1157        2759 :     maProtection.FillFromXF3( nTypeProt );
    1158        2759 :     maAlignment.FillFromXF8( nAlign, nMiscAttrib );
    1159        2759 :     maBorder.FillFromXF8( nBorder1, nBorder2 );
    1160        2759 :     maArea.FillFromXF8( nBorder2, nArea );
    1161        2759 : }
    1162             : 
    1163        2759 : void XclImpXF::ReadXF( XclImpStream& rStrm )
    1164             : {
    1165        2759 :     switch( GetBiff() )
    1166             :     {
    1167           0 :         case EXC_BIFF2: ReadXF2( rStrm );   break;
    1168           0 :         case EXC_BIFF3: ReadXF3( rStrm );   break;
    1169           0 :         case EXC_BIFF4: ReadXF4( rStrm );   break;
    1170           0 :         case EXC_BIFF5: ReadXF5( rStrm );   break;
    1171        2759 :         case EXC_BIFF8: ReadXF8( rStrm );   break;
    1172             :         default:        DBG_ERROR_BIFF();
    1173             :     }
    1174        2759 : }
    1175             : 
    1176      105307 : const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs )
    1177             : {
    1178      105307 :     if( mpPattern.get() )
    1179      103699 :         return *mpPattern;
    1180             : 
    1181             :     // create new pattern attribute set
    1182        1608 :     mpPattern.reset( new ScPatternAttr( GetDoc().GetPool() ) );
    1183        1608 :     SfxItemSet& rItemSet = mpPattern->GetItemSet();
    1184        1608 :     XclImpXF* pParentXF = IsCellXF() ? GetXFBuffer().GetXF( mnParent ) : 0;
    1185             : 
    1186             :     // parent cell style
    1187        1608 :     if( IsCellXF() && !mpStyleSheet )
    1188             :     {
    1189        1182 :         mpStyleSheet = GetXFBuffer().CreateStyleSheet( mnParent );
    1190             : 
    1191             :         /*  Enables mb***Used flags, if the formatting attributes differ from
    1192             :             the passed XF record. In cell XFs Excel uses the cell attributes,
    1193             :             if they differ from the parent style XF.
    1194             :             ...or if the respective flag is not set in parent style XF. */
    1195        1182 :         if( pParentXF )
    1196             :         {
    1197        1182 :             if( !mbProtUsed )
    1198        1161 :                 mbProtUsed = !pParentXF->mbProtUsed || !(maProtection == pParentXF->maProtection);
    1199        1182 :             if( !mbFontUsed )
    1200         437 :                 mbFontUsed = !pParentXF->mbFontUsed || (mnXclFont != pParentXF->mnXclFont);
    1201        1182 :             if( !mbFmtUsed )
    1202         632 :                 mbFmtUsed = !pParentXF->mbFmtUsed || (mnXclNumFmt != pParentXF->mnXclNumFmt);
    1203        1182 :             if( !mbAlignUsed )
    1204         335 :                 mbAlignUsed = !pParentXF->mbAlignUsed || !(maAlignment == pParentXF->maAlignment);
    1205        1182 :             if( !mbBorderUsed )
    1206         197 :                 mbBorderUsed = !pParentXF->mbBorderUsed || !(maBorder == pParentXF->maBorder);
    1207        1182 :             if( !mbAreaUsed )
    1208         264 :                 mbAreaUsed = !pParentXF->mbAreaUsed || !(maArea == pParentXF->maArea);
    1209             :         }
    1210             :     }
    1211             : 
    1212             :     // cell protection
    1213        1608 :     if( mbProtUsed )
    1214          87 :         maProtection.FillToItemSet( rItemSet, bSkipPoolDefs );
    1215             : 
    1216             :     // font
    1217        1608 :     if( mbFontUsed )
    1218        1160 :         GetFontBuffer().FillToItemSet( rItemSet, EXC_FONTITEM_CELL, mnXclFont, bSkipPoolDefs );
    1219             : 
    1220             :     // value format
    1221        1608 :     if( mbFmtUsed )
    1222             :     {
    1223         608 :         GetNumFmtBuffer().FillToItemSet( rItemSet, mnXclNumFmt, bSkipPoolDefs );
    1224             :         // Trace occurrences of Windows date formats
    1225         608 :         GetTracer().TraceDates( mnXclNumFmt );
    1226             :     }
    1227             : 
    1228             :     // alignment
    1229        1608 :     if( mbAlignUsed )
    1230         903 :         maAlignment.FillToItemSet( rItemSet, GetFontBuffer().GetFont( mnXclFont ), bSkipPoolDefs );
    1231             : 
    1232             :     // border
    1233        1608 :     if( mbBorderUsed )
    1234             :     {
    1235        1136 :         maBorder.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
    1236        3408 :         GetTracer().TraceBorderLineStyle(maBorder.mnLeftLine > EXC_LINE_HAIR ||
    1237        3408 :             maBorder.mnRightLine > EXC_LINE_HAIR || maBorder.mnTopLine > EXC_LINE_HAIR ||
    1238        3408 :             maBorder.mnBottomLine > EXC_LINE_HAIR );
    1239             :     }
    1240             : 
    1241             :     // area
    1242        1608 :     if( mbAreaUsed )
    1243             :     {
    1244        1270 :         maArea.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs );
    1245        3725 :         GetTracer().TraceFillPattern(maArea.mnPattern != EXC_PATT_NONE &&
    1246        3725 :             maArea.mnPattern != EXC_PATT_SOLID);
    1247             :     }
    1248             : 
    1249             :     /*  #i38709# Decide which rotation reference mode to use. If any outer
    1250             :         border line of the cell is set (either explicitly or via cell style),
    1251             :         and the cell contents are rotated, set rotation reference to bottom of
    1252             :         cell. This causes the borders to be painted rotated with the text. */
    1253        1608 :     if( mbAlignUsed || mbBorderUsed )
    1254             :     {
    1255        1207 :         SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
    1256        1207 :         const XclImpCellAlign* pAlign = mbAlignUsed ? &maAlignment : (pParentXF ? &pParentXF->maAlignment : 0);
    1257        1207 :         const XclImpCellBorder* pBorder = mbBorderUsed ? &maBorder : (pParentXF ? &pParentXF->maBorder : 0);
    1258        1207 :         if( pAlign && pBorder && (0 < pAlign->mnRotation) && (pAlign->mnRotation <= 180) && pBorder->HasAnyOuterBorder() )
    1259           3 :             eRotateMode = SVX_ROTATE_MODE_BOTTOM;
    1260        1207 :         ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
    1261             :     }
    1262             : 
    1263             :     // Excel's cell margins are different from Calc's default margins.
    1264        1608 :     SvxMarginItem aItem(40, 40, 40, 40, ATTR_MARGIN);
    1265        1608 :     ScfTools::PutItem(rItemSet, aItem, bSkipPoolDefs);
    1266             : 
    1267        1608 :     return *mpPattern;
    1268             : }
    1269             : 
    1270      104886 : void XclImpXF::ApplyPatternToAttrList(
    1271             :     list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2, sal_uInt32 nForceScNumFmt)
    1272             : {
    1273             :     // force creation of cell style and hard formatting, do it here to have mpStyleSheet
    1274      104886 :     CreatePattern();
    1275      104886 :     ScPatternAttr& rPat = *mpPattern;
    1276             : 
    1277             :     // insert into document
    1278      104886 :     ScDocument& rDoc = GetDoc();
    1279             : 
    1280      104886 :     if (IsCellXF())
    1281             :     {
    1282      104616 :         if (mpStyleSheet)
    1283             :         {
    1284             :             // Apply style sheet.  Don't clear the direct formats.
    1285      104616 :             rPat.SetStyleSheet(mpStyleSheet, false);
    1286             :         }
    1287             :         else
    1288             :         {
    1289             :             // When the cell format is not associated with any style, use the
    1290             :             // 'Default' style.  Some buggy XLS docs generated by apps other
    1291             :             // than Excel (such as 1C) may not have any built-in styles at
    1292             :             // all.
    1293           0 :             ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
    1294           0 :             if (pStylePool)
    1295             :             {
    1296             :                 ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>(
    1297             :                     pStylePool->Find(
    1298           0 :                         ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA));
    1299             : 
    1300           0 :                 if (pStyleSheet)
    1301           0 :                     rPat.SetStyleSheet(pStyleSheet, false);
    1302             :             }
    1303             : 
    1304             :         }
    1305             :     }
    1306             : 
    1307      104886 :     if (nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND)
    1308             :     {
    1309           0 :         ScPatternAttr aNumPat(rDoc.GetPool());
    1310           0 :         GetNumFmtBuffer().FillScFmtToItemSet(aNumPat.GetItemSet(), nForceScNumFmt);
    1311           0 :         rPat.GetItemSet().Put(aNumPat.GetItemSet());
    1312             :     }
    1313             : 
    1314             :     // Make sure we skip unnamed styles.
    1315      104886 :     if (rPat.GetStyleName())
    1316             :     {
    1317             :         // Check for a gap between the last entry and this one.
    1318      104616 :         bool bHasGap = false;
    1319      104616 :         if (rAttrs.empty() && nRow1 > 0)
    1320             :             // First attribute range doesn't start at row 0.
    1321        5742 :             bHasGap = true;
    1322             : 
    1323      104616 :         if (!rAttrs.empty() && rAttrs.back().nRow + 1 < nRow1)
    1324       14922 :             bHasGap = true;
    1325             : 
    1326      104616 :         if (bHasGap)
    1327             :         {
    1328             :             // Fill this gap with the default pattern.
    1329             :             ScAttrEntry aEntry;
    1330       20664 :             aEntry.nRow = nRow1 - 1;
    1331       20664 :             aEntry.pPattern = rDoc.GetDefPattern();
    1332       20664 :             rAttrs.push_back(aEntry);
    1333             :         }
    1334             : 
    1335             :         ScAttrEntry aEntry;
    1336      104616 :         aEntry.nRow = nRow2;
    1337      104616 :         aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(rPat));
    1338      104616 :         rAttrs.push_back(aEntry);
    1339             :     }
    1340      104886 : }
    1341             : 
    1342           0 : void XclImpXF::ApplyPattern(
    1343             :         SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2,
    1344             :         SCTAB nScTab, sal_uLong nForceScNumFmt )
    1345             : {
    1346             :     // force creation of cell style and hard formatting, do it here to have mpStyleSheet
    1347           0 :     const ScPatternAttr& rPattern = CreatePattern();
    1348             : 
    1349             :     // insert into document
    1350           0 :     ScDocument& rDoc = GetDoc();
    1351           0 :     if( IsCellXF() && mpStyleSheet )
    1352           0 :         rDoc.ApplyStyleAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, *mpStyleSheet );
    1353           0 :     if( HasUsedFlags() )
    1354           0 :         rDoc.ApplyPatternAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, rPattern );
    1355             : 
    1356             :     // #108770# apply special number format
    1357           0 :     if( nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
    1358             :     {
    1359           0 :         ScPatternAttr aPattern( GetDoc().GetPool() );
    1360           0 :         GetNumFmtBuffer().FillScFmtToItemSet( aPattern.GetItemSet(), nForceScNumFmt );
    1361           0 :         rDoc.ApplyPatternAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, aPattern );
    1362             :     }
    1363           0 : }
    1364             : 
    1365           0 : /*static*/ void XclImpXF::ApplyPatternForBiff2CellFormat( const XclImpRoot& rRoot,
    1366             :         const ScAddress& rScPos, sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 )
    1367             : {
    1368             :     /*  Create an XF object and let it do the work. We will have access to its
    1369             :         private members here. */
    1370           0 :     XclImpXF aXF( rRoot );
    1371             : 
    1372             :     // no used flags available in BIFF2 (always true)
    1373           0 :     aXF.SetAllUsedFlags( true );
    1374             : 
    1375             :     // set the attributes
    1376           0 :     aXF.maProtection.FillFromXF2( nFlags1 );
    1377           0 :     aXF.maAlignment.FillFromXF2( nFlags3 );
    1378           0 :     aXF.maBorder.FillFromXF2( nFlags3 );
    1379           0 :     aXF.maArea.FillFromXF2( nFlags3 );
    1380           0 :     aXF.mnXclNumFmt = ::extract_value< sal_uInt16 >( nFlags2, 0, 6 );
    1381           0 :     aXF.mnXclFont = ::extract_value< sal_uInt16 >( nFlags2, 6, 2 );
    1382             : 
    1383             :     // write the attributes to the cell
    1384           0 :     aXF.ApplyPattern( rScPos.Col(), rScPos.Row(), rScPos.Col(), rScPos.Row(), rScPos.Tab() );
    1385           0 : }
    1386             : 
    1387        2759 : void XclImpXF::SetUsedFlags( sal_uInt8 nUsedFlags )
    1388             : {
    1389             :     /*  Notes about finding the mb***Used flags:
    1390             :         - In cell XFs a *set* bit means a used attribute.
    1391             :         - In style XFs a *cleared* bit means a used attribute.
    1392             :         The mb***Used members always store true, if the attribute is used.
    1393             :         The "mbCellXF == ::get_flag(...)" construct evaluates to true in
    1394             :         both mentioned cases: cell XF and set bit; or style XF and cleared bit.
    1395             :      */
    1396        2759 :     mbProtUsed   = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_PROT ));
    1397        2759 :     mbFontUsed   = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_FONT ));
    1398        2759 :     mbFmtUsed    = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_VALFMT ));
    1399        2759 :     mbAlignUsed  = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_ALIGN ));
    1400        2759 :     mbBorderUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_BORDER ));
    1401        2759 :     mbAreaUsed   = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_AREA ));
    1402        2759 : }
    1403             : 
    1404             : // ----------------------------------------------------------------------------
    1405             : 
    1406         968 : XclImpStyle::XclImpStyle( const XclImpRoot& rRoot ) :
    1407             :     XclImpRoot( rRoot ),
    1408             :     mnXfId( EXC_XF_NOTFOUND ),
    1409             :     mnBuiltinId( EXC_STYLE_USERDEF ),
    1410             :     mnLevel( EXC_STYLE_NOLEVEL ),
    1411             :     mbBuiltin( false ),
    1412             :     mbCustom( false ),
    1413             :     mbHidden( false ),
    1414         968 :     mpStyleSheet( 0 )
    1415             : {
    1416         968 : }
    1417             : 
    1418         968 : void XclImpStyle::ReadStyle( XclImpStream& rStrm )
    1419             : {
    1420             :     OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF3 );
    1421             : 
    1422             :     sal_uInt16 nXFIndex;
    1423         968 :     rStrm >> nXFIndex;
    1424         968 :     mnXfId = nXFIndex & EXC_STYLE_XFMASK;
    1425         968 :     mbBuiltin = ::get_flag( nXFIndex, EXC_STYLE_BUILTIN );
    1426             : 
    1427         968 :     if( mbBuiltin )
    1428             :     {
    1429         307 :         rStrm >> mnBuiltinId >> mnLevel;
    1430             :     }
    1431             :     else
    1432             :     {
    1433         661 :         maName = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString();
    1434             :         // #i103281# check if this is a new built-in style introduced in XL2007
    1435         661 :         if( (GetBiff() == EXC_BIFF8) && (rStrm.GetNextRecId() == EXC_ID_STYLEEXT) && rStrm.StartNextRecord() )
    1436             :         {
    1437             :             sal_uInt8 nExtFlags;
    1438         289 :             rStrm.Ignore( 12 );
    1439         289 :             rStrm >> nExtFlags;
    1440         289 :             mbBuiltin = ::get_flag( nExtFlags, EXC_STYLEEXT_BUILTIN );
    1441         289 :             mbCustom = ::get_flag( nExtFlags, EXC_STYLEEXT_CUSTOM );
    1442         289 :             mbHidden = ::get_flag( nExtFlags, EXC_STYLEEXT_HIDDEN );
    1443         289 :             if( mbBuiltin )
    1444             :             {
    1445         287 :                 rStrm.Ignore( 1 );  // category
    1446         287 :                 rStrm >> mnBuiltinId >> mnLevel;
    1447             :             }
    1448             :         }
    1449             :     }
    1450         968 : }
    1451             : 
    1452        1556 : ScStyleSheet* XclImpStyle::CreateStyleSheet()
    1453             : {
    1454             :     // #i1624# #i1768# ignore unnamed user styles
    1455        1556 :     if( !mpStyleSheet && (maFinalName.Len() > 0) )
    1456             :     {
    1457         421 :         bool bCreatePattern = false;
    1458         421 :         XclImpXF* pXF = GetXFBuffer().GetXF( mnXfId );
    1459             : 
    1460         421 :         bool bDefStyle = mbBuiltin && (mnBuiltinId == EXC_STYLE_NORMAL);
    1461         421 :         if( bDefStyle )
    1462             :         {
    1463             :             // set all flags to true to get all items in XclImpXF::CreatePattern()
    1464          37 :             if( pXF ) pXF->SetAllUsedFlags( true );
    1465             :             // use existing "Default" style sheet
    1466          37 :             mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find(
    1467          37 :                 ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) );
    1468             :             OSL_ENSURE( mpStyleSheet, "XclImpStyle::CreateStyleSheet - Default style not found" );
    1469          37 :             bCreatePattern = true;
    1470             :         }
    1471             :         else
    1472             :         {
    1473             :             /*  #i103281# do not create another style sheet of the same name,
    1474             :                 if it exists already. This is needed to prevent that styles
    1475             :                 pasted from clipboard get duplicated over and over. */
    1476         384 :             mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find( maFinalName, SFX_STYLE_FAMILY_PARA ) );
    1477         384 :             if( !mpStyleSheet )
    1478             :             {
    1479         384 :                 mpStyleSheet = &static_cast< ScStyleSheet& >( GetStyleSheetPool().Make( maFinalName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) );
    1480         384 :                 bCreatePattern = true;
    1481             :             }
    1482             :         }
    1483             : 
    1484             :         // bDefStyle==true omits default pool items in CreatePattern()
    1485         421 :         if( bCreatePattern && mpStyleSheet && pXF )
    1486         421 :             mpStyleSheet->GetItemSet().Put( pXF->CreatePattern( bDefStyle ).GetItemSet() );
    1487             :     }
    1488        1556 :     return mpStyleSheet;
    1489             : }
    1490             : 
    1491         968 : void XclImpStyle::CreateUserStyle( const String& rFinalName )
    1492             : {
    1493         968 :     maFinalName = rFinalName;
    1494         968 :     if( !IsBuiltin() || mbCustom )
    1495         374 :         CreateStyleSheet();
    1496         968 : }
    1497             : 
    1498             : // ----------------------------------------------------------------------------
    1499             : 
    1500          46 : XclImpXFBuffer::XclImpXFBuffer( const XclImpRoot& rRoot ) :
    1501          46 :     XclImpRoot( rRoot )
    1502             : {
    1503          46 : }
    1504             : 
    1505           0 : void XclImpXFBuffer::Initialize()
    1506             : {
    1507           0 :     maXFList.clear();
    1508           0 :     maBuiltinStyles.clear();
    1509           0 :     maUserStyles.clear();
    1510           0 :     maStylesByXf.clear();
    1511           0 : }
    1512             : 
    1513        2759 : void XclImpXFBuffer::ReadXF( XclImpStream& rStrm )
    1514             : {
    1515        2759 :     XclImpXF* pXF = new XclImpXF( GetRoot() );
    1516        2759 :     pXF->ReadXF( rStrm );
    1517        2759 :     maXFList.push_back( pXF );
    1518        2759 : }
    1519             : 
    1520         968 : void XclImpXFBuffer::ReadStyle( XclImpStream& rStrm )
    1521             : {
    1522         968 :     XclImpStyle* pStyle = new XclImpStyle( GetRoot() );
    1523         968 :     pStyle->ReadStyle( rStrm );
    1524         968 :     (pStyle->IsBuiltin() ? maBuiltinStyles : maUserStyles).push_back( pStyle );
    1525             :     OSL_ENSURE( maStylesByXf.count( pStyle->GetXfId() ) == 0, "XclImpXFBuffer::ReadStyle - multiple styles with equal XF identifier" );
    1526         968 :     maStylesByXf[ pStyle->GetXfId() ] = pStyle;
    1527         968 : }
    1528             : 
    1529       10625 : sal_uInt16 XclImpXFBuffer::GetFontIndex( sal_uInt16 nXFIndex ) const
    1530             : {
    1531       10625 :     const XclImpXF* pXF = GetXF( nXFIndex );
    1532       10625 :     return pXF ? pXF->GetFontIndex() : EXC_FONT_NOTFOUND;
    1533             : }
    1534             : 
    1535       10625 : const XclImpFont* XclImpXFBuffer::GetFont( sal_uInt16 nXFIndex ) const
    1536             : {
    1537       10625 :     return GetFontBuffer().GetFont( GetFontIndex( nXFIndex ) );
    1538             : }
    1539             : 
    1540             : namespace {
    1541             : 
    1542             : /** Functor for case-insensitive string comparison, usable in maps etc. */
    1543             : struct IgnoreCaseCompare
    1544             : {
    1545       16131 :     inline bool operator()( const String& rName1, const String& rName2 ) const
    1546       16131 :         { return rName1.CompareIgnoreCaseToAscii( rName2 ) == COMPARE_LESS; }
    1547             : };
    1548             : 
    1549             : } // namespace
    1550             : 
    1551          45 : void XclImpXFBuffer::CreateUserStyles()
    1552             : {
    1553             :     // calculate final names of all styles
    1554             :     typedef ::std::map< String, XclImpStyle*, IgnoreCaseCompare > CellStyleNameMap;
    1555             :     typedef ::std::vector< XclImpStyle* > XclImpStyleVector;
    1556             : 
    1557          45 :     CellStyleNameMap aCellStyles;
    1558          90 :     XclImpStyleVector aConflictNameStyles;
    1559             : 
    1560             :     /*  First, reserve style names that are built-in in Calc. This causes that
    1561             :         imported cell styles get different unused names and thus do not try to
    1562             :         overwrite these built-in styles. For BIFF4 workbooks (which contain a
    1563             :         separate list of cell styles per sheet), reserve all existing styles if
    1564             :         current sheet is not the first sheet (this styles buffer will be
    1565             :         initialized again for every new sheet). This will create unique names
    1566             :         for styles in different sheets with the same name. Assuming that the
    1567             :         BIFF4W import filter is never used to import from clipboard... */
    1568          45 :     bool bReserveAll = (GetBiff() == EXC_BIFF4) && (GetCurrScTab() > 0);
    1569          90 :     SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
    1570          90 :     String aStandardName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
    1571         270 :     for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
    1572         225 :         if( (pStyleSheet->GetName() != aStandardName) && (bReserveAll || !pStyleSheet->IsUserDefined()) )
    1573         180 :             if( aCellStyles.count( pStyleSheet->GetName() ) == 0 )
    1574         180 :                 aCellStyles[ pStyleSheet->GetName() ] = 0;
    1575             : 
    1576             :     /*  Calculate names of built-in styles. Store styles with reserved names
    1577             :         in the aConflictNameStyles list. */
    1578         639 :     for( XclImpStyleList::iterator itStyle = maBuiltinStyles.begin(); itStyle != maBuiltinStyles.end(); ++itStyle )
    1579             :     {
    1580         594 :         String aStyleName = XclTools::GetBuiltInStyleName( itStyle->GetBuiltinId(), itStyle->GetName(), itStyle->GetLevel() );
    1581             :         OSL_ENSURE( bReserveAll || (aCellStyles.count( aStyleName ) == 0),
    1582             :             "XclImpXFBuffer::CreateUserStyles - multiple styles with equal built-in identifier" );
    1583         594 :         if( aCellStyles.count( aStyleName ) > 0 )
    1584           0 :             aConflictNameStyles.push_back( &(*itStyle) );
    1585             :         else
    1586         594 :             aCellStyles[ aStyleName ] = &(*itStyle);
    1587         594 :     }
    1588             : 
    1589             :     /*  Calculate names of user defined styles. Store styles with reserved
    1590             :         names in the aConflictNameStyles list. */
    1591         419 :     for( XclImpStyleList::iterator itStyle = maUserStyles.begin(); itStyle != maUserStyles.end(); ++itStyle )
    1592             :     {
    1593             :         // #i1624# #i1768# ignore unnamed user styles
    1594         374 :         if( itStyle->GetName().Len() > 0 )
    1595             :         {
    1596         374 :             if( aCellStyles.count( itStyle->GetName() ) > 0 )
    1597           0 :                 aConflictNameStyles.push_back( &(*itStyle) );
    1598             :             else
    1599         374 :                 aCellStyles[ itStyle->GetName() ] = &(*itStyle);
    1600             :         }
    1601             :     }
    1602             : 
    1603             :     // find unused names for all styles with conflicting names
    1604          45 :     for( XclImpStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
    1605             :     {
    1606           0 :         XclImpStyle* pStyle = *aIt;
    1607           0 :         String aUnusedName;
    1608           0 :         sal_Int32 nIndex = 0;
    1609           0 :         do
    1610             :         {
    1611           0 :             aUnusedName.Assign( pStyle->GetName() ).Append( ' ' ).Append( OUString::number( ++nIndex ) );
    1612             :         }
    1613           0 :         while( aCellStyles.count( aUnusedName ) > 0 );
    1614           0 :         aCellStyles[ aUnusedName ] = pStyle;
    1615           0 :     }
    1616             : 
    1617             :     // set final names and create user-defined and modified built-in cell styles
    1618        1193 :     for( CellStyleNameMap::iterator aIt = aCellStyles.begin(), aEnd = aCellStyles.end(); aIt != aEnd; ++aIt )
    1619        1148 :         if( aIt->second )
    1620        1013 :             aIt->second->CreateUserStyle( aIt->first );
    1621          45 : }
    1622             : 
    1623        1182 : ScStyleSheet* XclImpXFBuffer::CreateStyleSheet( sal_uInt16 nXFIndex )
    1624             : {
    1625        1182 :     XclImpStyleMap::iterator aIt = maStylesByXf.find( nXFIndex );
    1626        1182 :     return (aIt == maStylesByXf.end()) ? 0 : aIt->second->CreateStyleSheet();
    1627             : }
    1628             : 
    1629             : // Buffer for XF indexes in cells =============================================
    1630             : 
    1631           5 : IMPL_FIXEDMEMPOOL_NEWDEL( XclImpXFRange )
    1632             : 
    1633      541587 : bool XclImpXFRange::Expand( SCROW nScRow, const XclImpXFIndex& rXFIndex )
    1634             : {
    1635      541587 :     if( maXFIndex != rXFIndex )
    1636       61875 :         return false;
    1637             : 
    1638      479712 :     if( mnScRow2 + 1 == nScRow )
    1639             :     {
    1640      473510 :         ++mnScRow2;
    1641      473510 :         return true;
    1642             :     }
    1643        6202 :     if( mnScRow1 > 0 && (mnScRow1 - 1 == nScRow) )
    1644             :     {
    1645           0 :         --mnScRow1;
    1646           0 :         return true;
    1647             :     }
    1648             : 
    1649        6202 :     return false;
    1650             : }
    1651             : 
    1652        2348 : bool XclImpXFRange::Expand( const XclImpXFRange& rNextRange )
    1653             : {
    1654             :     OSL_ENSURE( mnScRow2 < rNextRange.mnScRow1, "XclImpXFRange::Expand - rows out of order" );
    1655        2348 :     if( (maXFIndex == rNextRange.maXFIndex) && (mnScRow2 + 1 == rNextRange.mnScRow1) )
    1656             :     {
    1657         570 :         mnScRow2 = rNextRange.mnScRow2;
    1658         570 :         return true;
    1659             :     }
    1660        1778 :     return false;
    1661             : }
    1662             : 
    1663             : // ----------------------------------------------------------------------------
    1664             : 
    1665       12722 : void XclImpXFRangeColumn::SetDefaultXF( const XclImpXFIndex& rXFIndex )
    1666             : {
    1667             :     // List should be empty when inserting the default column format.
    1668             :     // Later explicit SetXF() calls will break up this range.
    1669             :     OSL_ENSURE( maIndexList.empty(), "XclImpXFRangeColumn::SetDefaultXF - Setting Default Column XF is not empty" );
    1670             : 
    1671             :     // insert a complete row range with one insert.
    1672       12722 :     maIndexList.push_back( new XclImpXFRange( 0, MAXROW, rXFIndex ) );
    1673       12722 : }
    1674             : 
    1675             : // ----------------------------------------------------------------------------
    1676             : 
    1677      563049 : void XclImpXFRangeColumn::SetXF( SCROW nScRow, const XclImpXFIndex& rXFIndex )
    1678             : {
    1679             :     XclImpXFRange* pPrevRange;
    1680             :     XclImpXFRange* pNextRange;
    1681             :     sal_uLong nNextIndex;
    1682             : 
    1683      563049 :     Find( pPrevRange, pNextRange, nNextIndex, nScRow );
    1684             : 
    1685             :     // previous range:
    1686             :     // try to overwrite XF (if row is contained in) or try to expand range
    1687      563049 :     if( pPrevRange )
    1688             :     {
    1689      550524 :         if( pPrevRange->Contains( nScRow ) )        // overwrite old XF
    1690             :         {
    1691      300046 :             if( rXFIndex == pPrevRange->maXFIndex )
    1692      501283 :                 return;
    1693             : 
    1694      298904 :             SCROW nFirstScRow = pPrevRange->mnScRow1;
    1695      298904 :             SCROW nLastScRow = pPrevRange->mnScRow2;
    1696      298904 :             sal_uLong nIndex = nNextIndex - 1;
    1697      298904 :             XclImpXFRange* pThisRange = pPrevRange;
    1698      298904 :             pPrevRange = (nIndex > 0 && nIndex <= maIndexList.size()) ? &(maIndexList[ nIndex - 1 ]) : 0;
    1699             : 
    1700      298904 :             if( nFirstScRow == nLastScRow )         // replace solely XF
    1701             :             {
    1702        1067 :                 pThisRange->maXFIndex = rXFIndex;
    1703        1067 :                 TryConcatPrev( nNextIndex );        // try to concat. next with this
    1704        1067 :                 TryConcatPrev( nIndex );            // try to concat. this with previous
    1705             :             }
    1706      297837 :             else if( nFirstScRow == nScRow )        // replace first XF
    1707             :             {
    1708      291876 :                 ++(pThisRange->mnScRow1);
    1709             :                 // try to concatenate with previous of this
    1710      291876 :                 if( !pPrevRange || !pPrevRange->Expand( nScRow, rXFIndex ) )
    1711       18461 :                     Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
    1712             :             }
    1713        5961 :             else if( nLastScRow == nScRow )         // replace last XF
    1714             :             {
    1715           0 :                 --(pThisRange->mnScRow2);
    1716           0 :                 if( !pNextRange || !pNextRange->Expand( nScRow, rXFIndex ) )
    1717           0 :                     Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
    1718             :             }
    1719             :             else                                    // insert in the middle of the range
    1720             :             {
    1721        5961 :                 pThisRange->mnScRow1 = nScRow + 1;
    1722             :                 // List::Insert() moves entries towards end of list, so insert twice at nIndex
    1723        5961 :                 Insert( new XclImpXFRange( nScRow, rXFIndex ), nIndex );
    1724        5961 :                 Insert( new XclImpXFRange( nFirstScRow, nScRow - 1, pThisRange->maXFIndex ), nIndex );
    1725             :             }
    1726      298904 :             return;
    1727             :         }
    1728      250478 :         else if( pPrevRange->Expand( nScRow, rXFIndex ) )    // try to expand
    1729             :         {
    1730      200095 :             TryConcatPrev( nNextIndex );    // try to concatenate next with expanded
    1731      200095 :             return;
    1732             :         }
    1733             :     }
    1734             : 
    1735             :     // try to expand next range
    1736       62908 :     if( pNextRange && pNextRange->Expand( nScRow, rXFIndex ) )
    1737           0 :         return;
    1738             : 
    1739             :     // create new range
    1740       62908 :     Insert( new XclImpXFRange( nScRow, rXFIndex ), nNextIndex );
    1741             : }
    1742             : 
    1743       93291 : void XclImpXFRangeColumn::Insert(XclImpXFRange* pXFRange, sal_uLong nIndex)
    1744             : {
    1745       93291 :     maIndexList.insert( maIndexList.begin() + nIndex, pXFRange );
    1746       93291 : }
    1747             : 
    1748      563049 : void XclImpXFRangeColumn::Find(
    1749             :         XclImpXFRange*& rpPrevRange, XclImpXFRange*& rpNextRange,
    1750             :         sal_uLong& rnNextIndex, SCROW nScRow )
    1751             : {
    1752             : 
    1753             :     // test whether list is empty
    1754      563049 :     if( maIndexList.empty() )
    1755             :     {
    1756       12485 :         rpPrevRange = rpNextRange = 0;
    1757       12485 :         rnNextIndex = 0;
    1758       12485 :         return;
    1759             :     }
    1760             : 
    1761      550564 :     rpPrevRange = &maIndexList.front();
    1762      550564 :     rpNextRange = &maIndexList.back();
    1763             : 
    1764             :     // test whether row is at end of list (contained in or behind last range)
    1765             :     // rpPrevRange will contain a possible existing row
    1766      550564 :     if( rpNextRange->mnScRow1 <= nScRow )
    1767             :     {
    1768      540400 :         rpPrevRange = rpNextRange;
    1769      540400 :         rpNextRange = 0;
    1770      540400 :         rnNextIndex = maIndexList.size();
    1771      540400 :         return;
    1772             :     }
    1773             : 
    1774             :     // test whether row is at beginning of list (really before first range)
    1775       10164 :     if( nScRow < rpPrevRange->mnScRow1 )
    1776             :     {
    1777          40 :         rpNextRange = rpPrevRange;
    1778          40 :         rpPrevRange = 0;
    1779          40 :         rnNextIndex = 0;
    1780          40 :         return;
    1781             :     }
    1782             : 
    1783             :     // loop: find range entries before and after new row
    1784             :     // break the loop if there is no more range between first and last -or-
    1785             :     // if rpPrevRange contains nScRow (rpNextRange will never contain nScRow)
    1786       10124 :     sal_uLong nPrevIndex = 0;
    1787             :     sal_uLong nMidIndex;
    1788       10124 :     rnNextIndex = maIndexList.size() - 1;
    1789             :     XclImpXFRange* pMidRange;
    1790       53527 :     while( ((rnNextIndex - nPrevIndex) > 1) && (rpPrevRange->mnScRow2 < nScRow) )
    1791             :     {
    1792       33279 :         nMidIndex = (nPrevIndex + rnNextIndex) / 2;
    1793       33279 :         pMidRange = &maIndexList[nMidIndex];
    1794             :         OSL_ENSURE( pMidRange, "XclImpXFRangeColumn::Find - missing XF index range" );
    1795       33279 :         if( nScRow < pMidRange->mnScRow1 )      // row is really before pMidRange
    1796             :         {
    1797        5545 :             rpNextRange = pMidRange;
    1798        5545 :             rnNextIndex = nMidIndex;
    1799             :         }
    1800             :         else                                    // row is in or after pMidRange
    1801             :         {
    1802       27734 :             rpPrevRange = pMidRange;
    1803       27734 :             nPrevIndex = nMidIndex;
    1804             :         }
    1805             :     }
    1806             : 
    1807             :     // find next rpNextRange if rpPrevRange contains nScRow
    1808       10124 :     if( nScRow <= rpPrevRange->mnScRow2 )
    1809             :     {
    1810        8759 :         rnNextIndex = nPrevIndex + 1;
    1811        8759 :         rpNextRange = &maIndexList[rnNextIndex];
    1812             :     }
    1813             : }
    1814             : 
    1815      202229 : void XclImpXFRangeColumn::TryConcatPrev( sal_uLong nIndex )
    1816             : {
    1817      202229 :     if( !nIndex || nIndex >= maIndexList.size() )
    1818      402110 :         return;
    1819             : 
    1820        2348 :     XclImpXFRange& prevRange = maIndexList[ nIndex - 1 ];
    1821        2348 :     XclImpXFRange& nextRange = maIndexList[ nIndex ];
    1822             : 
    1823        2348 :     if( prevRange.Expand( nextRange ) )
    1824         570 :         maIndexList.erase( maIndexList.begin() + nIndex );
    1825             : }
    1826             : 
    1827             : // ----------------------------------------------------------------------------
    1828             : 
    1829          46 : XclImpXFRangeBuffer::XclImpXFRangeBuffer( const XclImpRoot& rRoot ) :
    1830          46 :     XclImpRoot( rRoot )
    1831             : {
    1832          46 : }
    1833             : 
    1834          92 : XclImpXFRangeBuffer::~XclImpXFRangeBuffer()
    1835             : {
    1836          92 : }
    1837             : 
    1838         156 : void XclImpXFRangeBuffer::Initialize()
    1839             : {
    1840         156 :     maColumns.clear();
    1841         156 :     maHyperlinks.clear();
    1842         156 :     maMergeList.RemoveAll();
    1843         156 : }
    1844             : 
    1845      563049 : void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex, XclImpXFInsertMode eMode )
    1846             : {
    1847      563049 :     SCCOL nScCol = rScPos.Col();
    1848      563049 :     SCROW nScRow = rScPos.Row();
    1849             : 
    1850             :     // set cell XF's
    1851      563049 :     size_t nIndex = static_cast< size_t >( nScCol );
    1852      563049 :     if( maColumns.size() <= nIndex )
    1853       12357 :         maColumns.resize( nIndex + 1 );
    1854      563049 :     if( !maColumns[ nIndex ] )
    1855       12485 :         maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
    1856             :     // remember all Boolean cells, they will get 'Standard' number format
    1857      563049 :     maColumns[ nIndex ]->SetXF( nScRow, XclImpXFIndex( nXFIndex, eMode == xlXFModeBoolCell ) );
    1858             : 
    1859             :     // set "center across selection" and "fill" attribute for all following empty cells
    1860             :     // ignore it on row default XFs
    1861      563049 :     if( eMode != xlXFModeRow )
    1862             :     {
    1863      243561 :         const XclImpXF* pXF = GetXFBuffer().GetXF( nXFIndex );
    1864      243561 :         if( pXF && ((pXF->GetHorAlign() == EXC_XF_HOR_CENTER_AS) || (pXF->GetHorAlign() == EXC_XF_HOR_FILL)) )
    1865             :         {
    1866             :             // expand last merged range if this attribute is set repeatedly
    1867           0 :             ScRange* pRange = maMergeList.empty() ? NULL : maMergeList.back();
    1868           0 :             if (pRange && (pRange->aEnd.Row() == nScRow) && (pRange->aEnd.Col() + 1 == nScCol) && (eMode == xlXFModeBlank))
    1869           0 :                 pRange->aEnd.IncCol();
    1870           0 :             else if( eMode != xlXFModeBlank )   // do not merge empty cells
    1871           0 :                 SetMerge( nScCol, nScRow );
    1872             :         }
    1873             :     }
    1874      563049 : }
    1875             : 
    1876       28458 : void XclImpXFRangeBuffer::SetXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
    1877             : {
    1878       28458 :     SetXF( rScPos, nXFIndex, xlXFModeCell );
    1879       28458 : }
    1880             : 
    1881      215103 : void XclImpXFRangeBuffer::SetBlankXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
    1882             : {
    1883      215103 :     SetXF( rScPos, nXFIndex, xlXFModeBlank );
    1884      215103 : }
    1885             : 
    1886           0 : void XclImpXFRangeBuffer::SetBoolXF( const ScAddress& rScPos, sal_uInt16 nXFIndex )
    1887             : {
    1888           0 :     SetXF( rScPos, nXFIndex, xlXFModeBoolCell );
    1889           0 : }
    1890             : 
    1891         312 : void XclImpXFRangeBuffer::SetRowDefXF( SCROW nScRow, sal_uInt16 nXFIndex )
    1892             : {
    1893      319800 :     for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
    1894      319488 :         SetXF( ScAddress( nScCol, nScRow, 0 ), nXFIndex, xlXFModeRow );
    1895         312 : }
    1896             : 
    1897       12722 : void XclImpXFRangeBuffer::SetColumnDefXF( SCCOL nScCol, sal_uInt16 nXFIndex )
    1898             : {
    1899             :     // our array should not have values when creating the default column format.
    1900       12722 :     size_t nIndex = static_cast< size_t >( nScCol );
    1901       12722 :     if( maColumns.size() <= nIndex )
    1902       12722 :         maColumns.resize( nIndex + 1 );
    1903             :     OSL_ENSURE( !maColumns[ nIndex ], "XclImpXFRangeBuffer::SetColumnDefXF - default column of XFs already has values" );
    1904       12722 :     maColumns[ nIndex ].reset( new XclImpXFRangeColumn );
    1905       12722 :     maColumns[ nIndex ]->SetDefaultXF( XclImpXFIndex( nXFIndex ) );
    1906       12722 : }
    1907             : 
    1908         438 : void XclImpXFRangeBuffer::SetBorderLine( const ScRange& rRange, SCTAB nScTab, sal_uInt16 nLine )
    1909             : {
    1910         438 :     SCCOL nFromScCol = (nLine == BOX_LINE_RIGHT) ? rRange.aEnd.Col() : rRange.aStart.Col();
    1911         438 :     SCROW nFromScRow = (nLine == BOX_LINE_BOTTOM) ? rRange.aEnd.Row() : rRange.aStart.Row();
    1912         438 :     ScDocument& rDoc = GetDoc();
    1913             : 
    1914             :     const SvxBoxItem* pFromItem = static_cast< const SvxBoxItem* >(
    1915         438 :         rDoc.GetAttr( nFromScCol, nFromScRow, nScTab, ATTR_BORDER ) );
    1916             :     const SvxBoxItem* pToItem = static_cast< const SvxBoxItem* >(
    1917         438 :         rDoc.GetAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, ATTR_BORDER ) );
    1918             : 
    1919         438 :     SvxBoxItem aNewItem( *pToItem );
    1920         438 :     aNewItem.SetLine( pFromItem->GetLine( nLine ), nLine );
    1921         438 :     rDoc.ApplyAttr( rRange.aStart.Col(), rRange.aStart.Row(), nScTab, aNewItem );
    1922         438 : }
    1923             : 
    1924           8 : void XclImpXFRangeBuffer::SetHyperlink( const XclRange& rXclRange, const String& rUrl )
    1925             : {
    1926           8 :     maHyperlinks.push_back( XclImpHyperlinkRange( rXclRange, rUrl ) );
    1927           8 : }
    1928             : 
    1929           0 : void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol, SCROW nScRow )
    1930             : {
    1931           0 :     maMergeList.Append( ScRange( nScCol, nScRow, 0 ) );
    1932           0 : }
    1933             : 
    1934         433 : void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2 )
    1935             : {
    1936         433 :     if( (nScCol1 < nScCol2) || (nScRow1 < nScRow2) )
    1937         433 :         maMergeList.Append( ScRange( nScCol1, nScRow1, 0, nScCol2, nScRow2, 0 ) );
    1938         433 : }
    1939             : 
    1940         156 : void XclImpXFRangeBuffer::Finalize()
    1941             : {
    1942         156 :     ScDocument& rDoc = GetDoc();
    1943         156 :     SCTAB nScTab = GetCurrScTab();
    1944             : 
    1945             :     // apply patterns
    1946         156 :     XclImpXFBuffer& rXFBuffer = GetXFBuffer();
    1947       25421 :     for( XclImpXFRangeColumnVec::const_iterator aVBeg = maColumns.begin(), aVEnd = maColumns.end(), aVIt = aVBeg; aVIt != aVEnd; ++aVIt )
    1948             :     {
    1949             :         // apply all cell styles of an existing column
    1950       25265 :         if( aVIt->get() )
    1951             :         {
    1952       25207 :             XclImpXFRangeColumn& rColumn = **aVIt;
    1953       25207 :             SCCOL nScCol = static_cast< SCCOL >( aVIt - aVBeg );
    1954       25207 :             list<ScAttrEntry> aAttrs;
    1955             : 
    1956      130650 :             for (XclImpXFRangeColumn::IndexList::iterator itr = rColumn.begin(), itrEnd = rColumn.end();
    1957             :                  itr != itrEnd; ++itr)
    1958             :             {
    1959      105443 :                 XclImpXFRange& rStyle = *itr;
    1960      105443 :                 const XclImpXFIndex& rXFIndex = rStyle.maXFIndex;
    1961      105443 :                 XclImpXF* pXF = rXFBuffer.GetXF( rXFIndex.GetXFIndex() );
    1962      105443 :                 if (!pXF)
    1963         557 :                     continue;
    1964             : 
    1965      104886 :                 sal_uInt32 nForceScNumFmt = rXFIndex.IsBoolCell() ?
    1966      104886 :                     GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND;
    1967             : 
    1968      104886 :                 pXF->ApplyPatternToAttrList(aAttrs, rStyle.mnScRow1, rStyle.mnScRow2, nForceScNumFmt);
    1969             :             }
    1970             : 
    1971       25207 :             if (aAttrs.empty() || aAttrs.back().nRow != MAXROW)
    1972             :             {
    1973             :                 ScAttrEntry aEntry;
    1974       12485 :                 aEntry.nRow = MAXROW;
    1975       12485 :                 aEntry.pPattern = rDoc.GetDefPattern();
    1976       12485 :                 aAttrs.push_back(aEntry);
    1977             :             }
    1978             : 
    1979       25207 :             size_t nAttrSize = aAttrs.size();
    1980             :             assert(nAttrSize > 0);
    1981       25207 :             ScAttrEntry* pData = new ScAttrEntry[nAttrSize];
    1982       25207 :             list<ScAttrEntry>::const_iterator itr = aAttrs.begin(), itrEnd = aAttrs.end();
    1983      162972 :             for (size_t i = 0; itr != itrEnd; ++itr, ++i)
    1984      137765 :                 pData[i] = *itr;
    1985             : 
    1986       25207 :             rDoc.SetAttrEntries(nScCol, nScTab, pData, static_cast<SCSIZE>(nAttrSize));
    1987             :         }
    1988             :     }
    1989             : 
    1990             :     // insert hyperlink cells
    1991         164 :     for( XclImpHyperlinkList::const_iterator aLIt = maHyperlinks.begin(), aLEnd = maHyperlinks.end(); aLIt != aLEnd; ++aLIt )
    1992           8 :         XclImpHyperlink::InsertUrl( GetRoot(), aLIt->first, aLIt->second );
    1993             : 
    1994             :     // apply cell merging
    1995         589 :     for ( size_t i = 0, nRange = maMergeList.size(); i < nRange; ++i )
    1996             :     {
    1997         433 :         const ScRange* pRange = maMergeList[ i ];
    1998         433 :         const ScAddress& rStart = pRange->aStart;
    1999         433 :         const ScAddress& rEnd = pRange->aEnd;
    2000         433 :         bool bMultiCol = rStart.Col() != rEnd.Col();
    2001         433 :         bool bMultiRow = rStart.Row() != rEnd.Row();
    2002             :         // set correct right border
    2003         433 :         if( bMultiCol )
    2004         433 :             SetBorderLine( *pRange, nScTab, BOX_LINE_RIGHT );
    2005             :         // set correct lower border
    2006         433 :         if( bMultiRow )
    2007           5 :             SetBorderLine( *pRange, nScTab, BOX_LINE_BOTTOM );
    2008             :         // do merge
    2009         433 :         if( bMultiCol || bMultiRow )
    2010         433 :             rDoc.DoMerge( nScTab, rStart.Col(), rStart.Row(), rEnd.Col(), rEnd.Row() );
    2011             :         // #i93609# merged range in a single row: test if manual row height is needed
    2012         433 :         if( !bMultiRow )
    2013             :         {
    2014         428 :             bool bTextWrap = static_cast< const SfxBoolItem* >( rDoc.GetAttr( rStart.Col(), rStart.Row(), rStart.Tab(), ATTR_LINEBREAK ) )->GetValue();
    2015         428 :             if( !bTextWrap && (rDoc.GetCellType( rStart ) == CELLTYPE_EDIT) )
    2016           0 :                 if (const EditTextObject* pEditObj = rDoc.GetEditText(rStart))
    2017           0 :                     bTextWrap = pEditObj->GetParagraphCount() > 1;
    2018         428 :             if( bTextWrap )
    2019           5 :                 GetOldRoot().pColRowBuff->SetManualRowHeight( rStart.Row() );
    2020             :         }
    2021             :     }
    2022         171 : }
    2023             : 
    2024             : // ============================================================================
    2025             : 
    2026             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10