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

Generated by: LCOV version 1.11