LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xetable.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 7 1194 0.6 %
Date: 2012-08-25 Functions: 2 144 1.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 1808 0.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "xetable.hxx"
      30                 :            : 
      31                 :            : #include <map>
      32                 :            : #include <com/sun/star/i18n/ScriptType.hpp>
      33                 :            : #include "scitems.hxx"
      34                 :            : #include <svl/intitem.hxx>
      35                 :            : #include "document.hxx"
      36                 :            : #include "dociter.hxx"
      37                 :            : #include "olinetab.hxx"
      38                 :            : #include "cell.hxx"
      39                 :            : #include "patattr.hxx"
      40                 :            : #include "attrib.hxx"
      41                 :            : #include "xehelper.hxx"
      42                 :            : #include "xecontent.hxx"
      43                 :            : #include "xeescher.hxx"
      44                 :            : #include "xeextlst.hxx"
      45                 :            : 
      46                 :            : using namespace ::oox;
      47                 :            : 
      48                 :            : using ::rtl::OString;
      49                 :            : using ::rtl::OUString;
      50                 :            : using ::rtl::OUStringBuffer;
      51                 :            : 
      52                 :            : namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
      53                 :            : 
      54                 :            : // ============================================================================
      55                 :            : // Helper records for cell records
      56                 :            : // ============================================================================
      57                 :            : 
      58                 :          0 : XclExpStringRec::XclExpStringRec( const XclExpRoot& rRoot, const String& rResult ) :
      59                 :            :     XclExpRecord( EXC_ID3_STRING ),
      60         [ #  # ]:          0 :     mxResult( XclExpStringHelper::CreateString( rRoot, rResult ) )
      61                 :            : {
      62                 :            :     OSL_ENSURE( (rRoot.GetBiff() <= EXC_BIFF5) || (mxResult->Len() > 0),
      63                 :            :         "XclExpStringRec::XclExpStringRec - empty result not allowed in BIFF8+" );
      64         [ #  # ]:          0 :     SetRecSize( mxResult->GetSize() );
      65                 :          0 : }
      66                 :            : 
      67                 :          0 : void XclExpStringRec::WriteBody( XclExpStream& rStrm )
      68                 :            : {
      69                 :          0 :     rStrm << *mxResult;
      70                 :          0 : }
      71                 :            : 
      72                 :            : // Additional records for special formula ranges ==============================
      73                 :            : 
      74                 :          0 : XclExpRangeFmlaBase::XclExpRangeFmlaBase(
      75                 :            :         sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScAddress& rScPos ) :
      76                 :            :     XclExpRecord( nRecId, nRecSize ),
      77                 :            :     maXclRange( ScAddress::UNINITIALIZED ),
      78                 :          0 :     maBaseXclPos( ScAddress::UNINITIALIZED )
      79                 :            : {
      80                 :          0 :     maBaseXclPos.Set( static_cast< sal_uInt16 >( rScPos.Col() ), static_cast< sal_uInt16 >( rScPos.Row() ) );
      81                 :          0 :     maXclRange.maFirst = maXclRange.maLast = maBaseXclPos;
      82                 :          0 : }
      83                 :            : 
      84                 :          0 : XclExpRangeFmlaBase::XclExpRangeFmlaBase(
      85                 :            :         sal_uInt16 nRecId, sal_uInt32 nRecSize, const ScRange& rScRange ) :
      86                 :            :     XclExpRecord( nRecId, nRecSize ),
      87                 :            :     maXclRange( ScAddress::UNINITIALIZED ),
      88                 :          0 :     maBaseXclPos( ScAddress::UNINITIALIZED )
      89                 :            : {
      90                 :            :     maXclRange.Set(
      91                 :          0 :         static_cast< sal_uInt16 >( rScRange.aStart.Col() ),
      92                 :          0 :         static_cast< sal_uInt16 >( rScRange.aStart.Row() ),
      93                 :          0 :         static_cast< sal_uInt16 >( rScRange.aEnd.Col() ),
      94                 :          0 :         static_cast< sal_uInt16 >( rScRange.aEnd.Row() ) );
      95                 :          0 :     maBaseXclPos = maXclRange.maFirst;
      96                 :          0 : }
      97                 :            : 
      98                 :          0 : bool XclExpRangeFmlaBase::IsBasePos( sal_uInt16 nXclCol, sal_uInt32 nXclRow ) const
      99                 :            : {
     100 [ #  # ][ #  # ]:          0 :     return (maBaseXclPos.mnCol == nXclCol) && (maBaseXclPos.mnRow == nXclRow);
     101                 :            : }
     102                 :            : 
     103                 :          0 : void XclExpRangeFmlaBase::Extend( const ScAddress& rScPos )
     104                 :            : {
     105                 :          0 :     sal_uInt16 nXclCol = static_cast< sal_uInt16 >( rScPos.Col() );
     106                 :          0 :     sal_uInt32 nXclRow = static_cast< sal_uInt32 >( rScPos.Row() );
     107         [ #  # ]:          0 :     maXclRange.maFirst.mnCol = ::std::min( maXclRange.maFirst.mnCol, nXclCol );
     108         [ #  # ]:          0 :     maXclRange.maFirst.mnRow = ::std::min( maXclRange.maFirst.mnRow, nXclRow );
     109         [ #  # ]:          0 :     maXclRange.maLast.mnCol  = ::std::max( maXclRange.maLast.mnCol,  nXclCol );
     110         [ #  # ]:          0 :     maXclRange.maLast.mnRow  = ::std::max( maXclRange.maLast.mnRow,  nXclRow );
     111                 :          0 : }
     112                 :            : 
     113                 :          0 : void XclExpRangeFmlaBase::WriteRangeAddress( XclExpStream& rStrm ) const
     114                 :            : {
     115                 :          0 :     maXclRange.Write( rStrm, false );
     116                 :          0 : }
     117                 :            : 
     118                 :            : // Array formulas =============================================================
     119                 :            : 
     120                 :          0 : XclExpArray::XclExpArray( XclTokenArrayRef xTokArr, const ScRange& rScRange ) :
     121                 :          0 :     XclExpRangeFmlaBase( EXC_ID3_ARRAY, 14 + xTokArr->GetSize(), rScRange ),
     122         [ #  # ]:          0 :     mxTokArr( xTokArr )
     123                 :            : {
     124                 :          0 : }
     125                 :            : 
     126                 :          0 : XclTokenArrayRef XclExpArray::CreateCellTokenArray( const XclExpRoot& rRoot ) const
     127                 :            : {
     128                 :          0 :     return rRoot.GetFormulaCompiler().CreateSpecialRefFormula( EXC_TOKID_EXP, maBaseXclPos );
     129                 :            : }
     130                 :            : 
     131                 :          0 : bool XclExpArray::IsVolatile() const
     132                 :            : {
     133                 :          0 :     return mxTokArr->IsVolatile();
     134                 :            : }
     135                 :            : 
     136                 :          0 : void XclExpArray::WriteBody( XclExpStream& rStrm )
     137                 :            : {
     138         [ #  # ]:          0 :     WriteRangeAddress( rStrm );
     139                 :          0 :     sal_uInt16 nFlags = EXC_ARRAY_DEFAULTFLAGS;
     140         [ #  # ]:          0 :     ::set_flag( nFlags, EXC_ARRAY_RECALC_ALWAYS, IsVolatile() );
     141 [ #  # ][ #  # ]:          0 :     rStrm << nFlags << sal_uInt32( 0 ) << *mxTokArr;
                 [ #  # ]
     142                 :          0 : }
     143                 :            : 
     144                 :            : // ----------------------------------------------------------------------------
     145                 :            : 
     146                 :          0 : XclExpArrayBuffer::XclExpArrayBuffer( const XclExpRoot& rRoot ) :
     147         [ #  # ]:          0 :     XclExpRoot( rRoot )
     148                 :            : {
     149                 :          0 : }
     150                 :            : 
     151                 :          0 : XclExpArrayRef XclExpArrayBuffer::CreateArray( const ScTokenArray& rScTokArr, const ScRange& rScRange )
     152                 :            : {
     153                 :          0 :     const ScAddress& rScPos = rScRange.aStart;
     154 [ #  # ][ #  # ]:          0 :     XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_MATRIX, rScTokArr, &rScPos );
     155                 :            : 
     156                 :            :     OSL_ENSURE( maRecMap.find( rScPos ) == maRecMap.end(), "XclExpArrayBuffer::CreateArray - array exists already" );
     157         [ #  # ]:          0 :     XclExpArrayRef& rxRec = maRecMap[ rScPos ];
     158 [ #  # ][ #  # ]:          0 :     rxRec.reset( new XclExpArray( xTokArr, rScRange ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     159 [ #  # ][ #  # ]:          0 :     return rxRec;
     160                 :            : }
     161                 :            : 
     162                 :          0 : XclExpArrayRef XclExpArrayBuffer::FindArray( const ScTokenArray& rScTokArr ) const
     163                 :            : {
     164                 :          0 :     XclExpArrayRef xRec;
     165                 :            :     // try to extract a matrix reference token
     166         [ #  # ]:          0 :     if( rScTokArr.GetLen() == 1 )
     167                 :            :     {
     168                 :          0 :         const formula::FormulaToken* pToken = rScTokArr.GetArray()[ 0 ];
     169 [ #  # ][ #  # ]:          0 :         if( pToken && (pToken->GetOpCode() == ocMatRef) )
                 [ #  # ]
     170                 :            :         {
     171         [ #  # ]:          0 :             const ScSingleRefData& rRef = static_cast<const ScToken*>(pToken)->GetSingleRef();
     172                 :          0 :             ScAddress aBasePos( rRef.nCol, rRef.nRow, GetCurrScTab() );
     173         [ #  # ]:          0 :             XclExpArrayMap::const_iterator aIt = maRecMap.find( aBasePos );
     174         [ #  # ]:          0 :             if( aIt != maRecMap.end() )
     175         [ #  # ]:          0 :                 xRec = aIt->second;
     176                 :            :         }
     177                 :            :     }
     178                 :          0 :     return xRec;
     179                 :            : }
     180                 :            : 
     181                 :            : // Shared formulas ============================================================
     182                 :            : 
     183                 :          0 : XclExpShrfmla::XclExpShrfmla( XclTokenArrayRef xTokArr, const ScAddress& rScPos ) :
     184                 :          0 :     XclExpRangeFmlaBase( EXC_ID_SHRFMLA, 10 + xTokArr->GetSize(), rScPos ),
     185                 :            :     mxTokArr( xTokArr ),
     186         [ #  # ]:          0 :     mnUsedCount( 1 )
     187                 :            : {
     188                 :          0 : }
     189                 :            : 
     190                 :          0 : void XclExpShrfmla::ExtendRange( const ScAddress& rScPos )
     191                 :            : {
     192                 :          0 :     Extend( rScPos );
     193                 :          0 :     ++mnUsedCount;
     194                 :          0 : }
     195                 :            : 
     196                 :          0 : XclTokenArrayRef XclExpShrfmla::CreateCellTokenArray( const XclExpRoot& rRoot ) const
     197                 :            : {
     198                 :          0 :     return rRoot.GetFormulaCompiler().CreateSpecialRefFormula( EXC_TOKID_EXP, maBaseXclPos );
     199                 :            : }
     200                 :            : 
     201                 :          0 : bool XclExpShrfmla::IsVolatile() const
     202                 :            : {
     203                 :          0 :     return mxTokArr->IsVolatile();
     204                 :            : }
     205                 :            : 
     206                 :          0 : void XclExpShrfmla::WriteBody( XclExpStream& rStrm )
     207                 :            : {
     208                 :          0 :     WriteRangeAddress( rStrm );
     209                 :          0 :     rStrm << sal_uInt8( 0 ) << mnUsedCount << *mxTokArr;
     210                 :          0 : }
     211                 :            : 
     212                 :            : // ----------------------------------------------------------------------------
     213                 :            : 
     214                 :          0 : XclExpShrfmlaBuffer::XclExpShrfmlaBuffer( const XclExpRoot& rRoot ) :
     215         [ #  # ]:          0 :     XclExpRoot( rRoot )
     216                 :            : {
     217                 :          0 : }
     218                 :            : 
     219                 :          0 : XclExpShrfmlaRef XclExpShrfmlaBuffer::CreateOrExtendShrfmla(
     220                 :            :         const ScTokenArray& rScTokArr, const ScAddress& rScPos )
     221                 :            : {
     222                 :          0 :     XclExpShrfmlaRef xRec;
     223 [ #  # ][ #  # ]:          0 :     if( const ScTokenArray* pShrdScTokArr = XclTokenArrayHelper::GetSharedFormula( GetRoot(), rScTokArr ) )
     224                 :            :     {
     225         [ #  # ]:          0 :         XclExpShrfmlaMap::iterator aIt = maRecMap.find( pShrdScTokArr );
     226         [ #  # ]:          0 :         if( aIt == maRecMap.end() )
     227                 :            :         {
     228                 :            :             // create a new record
     229 [ #  # ][ #  # ]:          0 :             XclTokenArrayRef xTokArr = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_SHARED, *pShrdScTokArr, &rScPos );
     230 [ #  # ][ #  # ]:          0 :             xRec.reset( new XclExpShrfmla( xTokArr, rScPos ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     231 [ #  # ][ #  # ]:          0 :             maRecMap[ pShrdScTokArr ] = xRec;
                 [ #  # ]
     232                 :            :         }
     233                 :            :         else
     234                 :            :         {
     235                 :            :             // extend existing record
     236                 :            :             OSL_ENSURE( aIt->second, "XclExpShrfmlaBuffer::CreateOrExtendShrfmla - missing record" );
     237         [ #  # ]:          0 :             xRec = aIt->second;
     238         [ #  # ]:          0 :             xRec->ExtendRange( rScPos );
     239                 :            :         }
     240                 :            :     }
     241                 :          0 :     return xRec;
     242                 :            : }
     243                 :            : 
     244                 :            : // Multiple operations ========================================================
     245                 :            : 
     246                 :          0 : XclExpTableop::XclExpTableop( const ScAddress& rScPos,
     247                 :            :         const XclMultipleOpRefs& rRefs, sal_uInt8 nScMode ) :
     248                 :            :     XclExpRangeFmlaBase( EXC_ID3_TABLEOP, 16, rScPos ),
     249                 :          0 :     mnLastAppXclCol( static_cast< sal_uInt16 >( rScPos.Col() ) ),
     250                 :          0 :     mnColInpXclCol( static_cast< sal_uInt16 >( rRefs.maColFirstScPos.Col() ) ),
     251                 :          0 :     mnColInpXclRow( static_cast< sal_uInt16 >( rRefs.maColFirstScPos.Row() ) ),
     252                 :          0 :     mnRowInpXclCol( static_cast< sal_uInt16 >( rRefs.maRowFirstScPos.Col() ) ),
     253                 :          0 :     mnRowInpXclRow( static_cast< sal_uInt16 >( rRefs.maRowFirstScPos.Row() ) ),
     254                 :            :     mnScMode( nScMode ),
     255                 :          0 :     mbValid( false )
     256                 :            : {
     257                 :          0 : }
     258                 :            : 
     259                 :          0 : bool XclExpTableop::TryExtend( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs )
     260                 :            : {
     261                 :          0 :     sal_uInt16 nXclCol = static_cast< sal_uInt16 >( rScPos.Col() );
     262                 :          0 :     sal_uInt16 nXclRow = static_cast< sal_uInt16 >( rScPos.Row() );
     263                 :            : 
     264                 :          0 :     bool bOk = IsAppendable( nXclCol, nXclRow );
     265         [ #  # ]:          0 :     if( bOk )
     266                 :            :     {
     267                 :          0 :         SCCOL nFirstScCol  = static_cast< SCCOL >( maXclRange.maFirst.mnCol );
     268                 :          0 :         SCROW nFirstScRow  = static_cast< SCROW >( maXclRange.maFirst.mnRow );
     269                 :          0 :         SCCOL nColInpScCol = static_cast< SCCOL >( mnColInpXclCol );
     270                 :          0 :         SCROW nColInpScRow = static_cast< SCROW >( mnColInpXclRow );
     271                 :          0 :         SCCOL nRowInpScCol = static_cast< SCCOL >( mnRowInpXclCol );
     272                 :          0 :         SCROW nRowInpScRow = static_cast< SCROW >( mnRowInpXclRow );
     273                 :            : 
     274                 :            :         bOk =   ((mnScMode == 2) == rRefs.mbDblRefMode) &&
     275                 :          0 :                 (rScPos.Tab() == rRefs.maFmlaScPos.Tab()) &&
     276                 :          0 :                 (nColInpScCol == rRefs.maColFirstScPos.Col()) &&
     277                 :          0 :                 (nColInpScRow == rRefs.maColFirstScPos.Row()) &&
     278                 :          0 :                 (rScPos.Tab() == rRefs.maColFirstScPos.Tab()) &&
     279   [ #  #  #  #  :          0 :                 (rScPos.Tab() == rRefs.maColRelScPos.Tab());
          #  #  #  #  #  
              # ][ #  # ]
     280                 :            : 
     281         [ #  # ]:          0 :         if( bOk ) switch( mnScMode )
           [ #  #  #  # ]
     282                 :            :         {
     283                 :            :             case 0:
     284                 :          0 :                 bOk =   (rScPos.Col() == rRefs.maFmlaScPos.Col()) &&
     285                 :          0 :                         (nFirstScRow  == rRefs.maFmlaScPos.Row() + 1) &&
     286                 :          0 :                         (nFirstScCol  == rRefs.maColRelScPos.Col() + 1) &&
     287 [ #  # ][ #  #  :          0 :                         (rScPos.Row() == rRefs.maColRelScPos.Row());
             #  #  #  # ]
     288                 :          0 :             break;
     289                 :            :             case 1:
     290                 :          0 :                 bOk =   (nFirstScCol  == rRefs.maFmlaScPos.Col() + 1) &&
     291                 :          0 :                         (rScPos.Row() == rRefs.maFmlaScPos.Row()) &&
     292                 :          0 :                         (rScPos.Col() == rRefs.maColRelScPos.Col()) &&
     293 [ #  # ][ #  #  :          0 :                         (nFirstScRow  == rRefs.maColRelScPos.Row() + 1);
             #  #  #  # ]
     294                 :          0 :             break;
     295                 :            :             case 2:
     296                 :          0 :                 bOk =   (nFirstScCol  == rRefs.maFmlaScPos.Col() + 1) &&
     297                 :          0 :                         (nFirstScRow  == rRefs.maFmlaScPos.Row() + 1) &&
     298                 :          0 :                         (nFirstScCol  == rRefs.maColRelScPos.Col() + 1) &&
     299                 :          0 :                         (rScPos.Row() == rRefs.maColRelScPos.Row()) &&
     300                 :          0 :                         (nRowInpScCol == rRefs.maRowFirstScPos.Col()) &&
     301                 :          0 :                         (nRowInpScRow == rRefs.maRowFirstScPos.Row()) &&
     302                 :          0 :                         (rScPos.Tab() == rRefs.maRowFirstScPos.Tab()) &&
     303                 :          0 :                         (rScPos.Col() == rRefs.maRowRelScPos.Col()) &&
     304                 :          0 :                         (nFirstScRow  == rRefs.maRowRelScPos.Row() + 1) &&
     305 [ #  # ][ #  #  :          0 :                         (rScPos.Tab() == rRefs.maRowRelScPos.Tab());
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     306                 :          0 :             break;
     307                 :            :             default:
     308                 :          0 :                 bOk = false;
     309                 :            :         }
     310                 :            : 
     311         [ #  # ]:          0 :         if( bOk )
     312                 :            :         {
     313                 :            :             // extend the cell range
     314                 :            :             OSL_ENSURE( IsAppendable( nXclCol, nXclRow ), "XclExpTableop::TryExtend - wrong cell address" );
     315                 :          0 :             Extend( rScPos );
     316                 :          0 :             mnLastAppXclCol = nXclCol;
     317                 :            :         }
     318                 :            :     }
     319                 :            : 
     320                 :          0 :     return bOk;
     321                 :            : }
     322                 :            : 
     323                 :          0 : void XclExpTableop::Finalize()
     324                 :            : {
     325                 :            :     // is the range complete? (last appended cell is in last column)
     326                 :          0 :     mbValid = maXclRange.maLast.mnCol == mnLastAppXclCol;
     327                 :            :     // if last row is incomplete, try to shorten the used range
     328 [ #  # ][ #  # ]:          0 :     if( !mbValid && (maXclRange.maFirst.mnRow < maXclRange.maLast.mnRow) )
     329                 :            :     {
     330                 :          0 :         --maXclRange.maLast.mnRow;
     331                 :          0 :         mbValid = true;
     332                 :            :     }
     333                 :            : 
     334                 :            :     // check if referred cells are outside of own range
     335         [ #  # ]:          0 :     if( mbValid ) switch( mnScMode )
           [ #  #  #  # ]
     336                 :            :     {
     337                 :            :         case 0:
     338                 :            :             mbValid =   (mnColInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
     339 [ #  # ][ #  # ]:          0 :                         (mnColInpXclRow     < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow);
         [ #  # ][ #  # ]
     340                 :          0 :         break;
     341                 :            :         case 1:
     342                 :            :             mbValid =   (mnColInpXclCol     < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
     343 [ #  # ][ #  # ]:          0 :                         (mnColInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow);
         [ #  # ][ #  # ]
     344                 :          0 :         break;
     345                 :            :         case 2:
     346                 :            :             mbValid =   ((mnColInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnColInpXclCol > maXclRange.maLast.mnCol) ||
     347                 :            :                          (mnColInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnColInpXclRow > maXclRange.maLast.mnRow)) &&
     348                 :            :                         ((mnRowInpXclCol + 1 < maXclRange.maFirst.mnCol) || (mnRowInpXclCol > maXclRange.maLast.mnCol) ||
     349 [ #  # ][ #  # ]:          0 :                          (mnRowInpXclRow + 1 < maXclRange.maFirst.mnRow) || (mnRowInpXclRow > maXclRange.maLast.mnRow));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     350                 :          0 :         break;
     351                 :            :     }
     352                 :          0 : }
     353                 :            : 
     354                 :          0 : XclTokenArrayRef XclExpTableop::CreateCellTokenArray( const XclExpRoot& rRoot ) const
     355                 :            : {
     356                 :          0 :     XclExpFormulaCompiler& rFmlaComp = rRoot.GetFormulaCompiler();
     357                 :            :     return mbValid ?
     358                 :            :         rFmlaComp.CreateSpecialRefFormula( EXC_TOKID_TBL, maBaseXclPos ) :
     359         [ #  # ]:          0 :         rFmlaComp.CreateErrorFormula( EXC_ERR_NA );
     360                 :            : }
     361                 :            : 
     362                 :          0 : bool XclExpTableop::IsVolatile() const
     363                 :            : {
     364                 :          0 :     return true;
     365                 :            : }
     366                 :            : 
     367                 :          0 : void XclExpTableop::Save( XclExpStream& rStrm )
     368                 :            : {
     369         [ #  # ]:          0 :     if( mbValid )
     370                 :          0 :         XclExpRangeFmlaBase::Save( rStrm );
     371                 :          0 : }
     372                 :            : 
     373                 :          0 : bool XclExpTableop::IsAppendable( sal_uInt16 nXclCol, sal_uInt16 nXclRow ) const
     374                 :            : {
     375                 :            :     return  ((nXclCol == mnLastAppXclCol + 1) && (nXclRow == maXclRange.maFirst.mnRow)) ||
     376                 :            :             ((nXclCol == mnLastAppXclCol + 1) && (nXclCol <= maXclRange.maLast.mnCol) && (nXclRow == maXclRange.maLast.mnRow)) ||
     377 [ #  # ][ #  # ]:          0 :             ((mnLastAppXclCol == maXclRange.maLast.mnCol) && (nXclCol == maXclRange.maFirst.mnCol) && (nXclRow == maXclRange.maLast.mnRow + 1));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     378                 :            : }
     379                 :            : 
     380                 :          0 : void XclExpTableop::WriteBody( XclExpStream& rStrm )
     381                 :            : {
     382                 :          0 :     sal_uInt16 nFlags = EXC_TABLEOP_DEFAULTFLAGS;
     383         [ #  # ]:          0 :     ::set_flag( nFlags, EXC_TABLEOP_RECALC_ALWAYS, IsVolatile() );
     384      [ #  #  # ]:          0 :     switch( mnScMode )
     385                 :            :     {
     386                 :          0 :         case 1: ::set_flag( nFlags, EXC_TABLEOP_ROW );  break;
     387                 :          0 :         case 2: ::set_flag( nFlags, EXC_TABLEOP_BOTH ); break;
     388                 :            :     }
     389                 :            : 
     390         [ #  # ]:          0 :     WriteRangeAddress( rStrm );
     391         [ #  # ]:          0 :     rStrm << nFlags;
     392         [ #  # ]:          0 :     if( mnScMode == 2 )
     393 [ #  # ][ #  # ]:          0 :         rStrm << mnRowInpXclRow << mnRowInpXclCol << mnColInpXclRow << mnColInpXclCol;
         [ #  # ][ #  # ]
     394                 :            :     else
     395 [ #  # ][ #  # ]:          0 :         rStrm << mnColInpXclRow << mnColInpXclCol << sal_uInt32( 0 );
                 [ #  # ]
     396                 :          0 : }
     397                 :            : 
     398                 :            : // ----------------------------------------------------------------------------
     399                 :            : 
     400                 :          0 : XclExpTableopBuffer::XclExpTableopBuffer( const XclExpRoot& rRoot ) :
     401         [ #  # ]:          0 :     XclExpRoot( rRoot )
     402                 :            : {
     403                 :          0 : }
     404                 :            : 
     405                 :          0 : XclExpTableopRef XclExpTableopBuffer::CreateOrExtendTableop(
     406                 :            :         const ScTokenArray& rScTokArr, const ScAddress& rScPos )
     407                 :            : {
     408         [ #  # ]:          0 :     XclExpTableopRef xRec;
     409                 :            : 
     410                 :            :     // try to extract cell references of a multiple operations formula
     411                 :          0 :     XclMultipleOpRefs aRefs;
     412 [ #  # ][ #  # ]:          0 :     if( XclTokenArrayHelper::GetMultipleOpRefs( aRefs, rScTokArr ) )
     413                 :            :     {
     414                 :            :         // try to find an existing TABLEOP record for this cell position
     415 [ #  # ][ #  # ]:          0 :         for( size_t nPos = 0, nSize = maTableopList.GetSize(); !xRec && (nPos < nSize); ++nPos )
                 [ #  # ]
     416                 :            :         {
     417         [ #  # ]:          0 :             XclExpTableopRef xTempRec = maTableopList.GetRecord( nPos );
     418 [ #  # ][ #  # ]:          0 :             if( xTempRec->TryExtend( rScPos, aRefs ) )
     419         [ #  # ]:          0 :                 xRec = xTempRec;
     420         [ #  # ]:          0 :         }
     421                 :            : 
     422                 :            :         // no record found, or found record not extensible
     423         [ #  # ]:          0 :         if( !xRec )
     424 [ #  # ][ #  # ]:          0 :             xRec = TryCreate( rScPos, aRefs );
                 [ #  # ]
     425                 :            :     }
     426                 :            : 
     427                 :          0 :     return xRec;
     428                 :            : }
     429                 :            : 
     430                 :          0 : void XclExpTableopBuffer::Finalize()
     431                 :            : {
     432         [ #  # ]:          0 :     for( size_t nPos = 0, nSize = maTableopList.GetSize(); nPos < nSize; ++nPos )
     433                 :          0 :         maTableopList.GetRecord( nPos )->Finalize();
     434                 :          0 : }
     435                 :            : 
     436                 :          0 : XclExpTableopRef XclExpTableopBuffer::TryCreate( const ScAddress& rScPos, const XclMultipleOpRefs& rRefs )
     437                 :            : {
     438                 :          0 :     sal_uInt8 nScMode = 0;
     439                 :          0 :     bool bOk =  (rScPos.Tab() == rRefs.maFmlaScPos.Tab()) &&
     440                 :          0 :                 (rScPos.Tab() == rRefs.maColFirstScPos.Tab()) &&
     441         [ #  # ]:          0 :                 (rScPos.Tab() == rRefs.maColRelScPos.Tab());
           [ #  #  #  # ]
     442                 :            : 
     443         [ #  # ]:          0 :     if( bOk )
     444                 :            :     {
     445         [ #  # ]:          0 :         if( rRefs.mbDblRefMode )
     446                 :            :         {
     447                 :          0 :             nScMode = 2;
     448                 :          0 :             bOk =   (rScPos.Col() == rRefs.maFmlaScPos.Col() + 1) &&
     449                 :          0 :                     (rScPos.Row() == rRefs.maFmlaScPos.Row() + 1) &&
     450                 :          0 :                     (rScPos.Col() == rRefs.maColRelScPos.Col() + 1) &&
     451                 :          0 :                     (rScPos.Row() == rRefs.maColRelScPos.Row()) &&
     452                 :          0 :                     (rScPos.Tab() == rRefs.maRowFirstScPos.Tab()) &&
     453                 :          0 :                     (rScPos.Col() == rRefs.maRowRelScPos.Col()) &&
     454                 :          0 :                     (rScPos.Row() == rRefs.maRowRelScPos.Row() + 1) &&
     455 [ #  # ][ #  #  :          0 :                     (rScPos.Tab() == rRefs.maRowRelScPos.Tab());
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     456                 :            :         }
     457   [ #  #  #  #  :          0 :         else if( (rScPos.Col() == rRefs.maFmlaScPos.Col()) &&
             #  #  #  # ]
                 [ #  # ]
     458                 :          0 :                  (rScPos.Row() == rRefs.maFmlaScPos.Row() + 1) &&
     459                 :          0 :                  (rScPos.Col() == rRefs.maColRelScPos.Col() + 1) &&
     460                 :          0 :                  (rScPos.Row() == rRefs.maColRelScPos.Row()) )
     461                 :            :         {
     462                 :          0 :             nScMode = 0;
     463                 :            :         }
     464   [ #  #  #  #  :          0 :         else if( (rScPos.Col() == rRefs.maFmlaScPos.Col() + 1) &&
             #  #  #  # ]
                 [ #  # ]
     465                 :          0 :                  (rScPos.Row() == rRefs.maFmlaScPos.Row()) &&
     466                 :          0 :                  (rScPos.Col() == rRefs.maColRelScPos.Col()) &&
     467                 :          0 :                  (rScPos.Row() == rRefs.maColRelScPos.Row() + 1) )
     468                 :            :         {
     469                 :          0 :             nScMode = 1;
     470                 :            :         }
     471                 :            :         else
     472                 :            :         {
     473                 :          0 :             bOk = false;
     474                 :            :         }
     475                 :            :     }
     476                 :            : 
     477                 :          0 :     XclExpTableopRef xRec;
     478         [ #  # ]:          0 :     if( bOk )
     479                 :            :     {
     480 [ #  # ][ #  # ]:          0 :         xRec.reset( new XclExpTableop( rScPos, rRefs, nScMode ) );
                 [ #  # ]
     481 [ #  # ][ #  # ]:          0 :         maTableopList.AppendRecord( xRec );
                 [ #  # ]
     482                 :            :     }
     483                 :            : 
     484                 :          0 :     return xRec;
     485                 :            : }
     486                 :            : 
     487                 :            : // ============================================================================
     488                 :            : // Cell records
     489                 :            : // ============================================================================
     490                 :            : 
     491                 :          0 : XclExpCellBase::XclExpCellBase(
     492                 :            :         sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos ) :
     493                 :            :     XclExpRecord( nRecId, nContSize + 4 ),
     494                 :          0 :     maXclPos( rXclPos )
     495                 :            : {
     496                 :          0 : }
     497                 :            : 
     498                 :          0 : bool XclExpCellBase::IsMultiLineText() const
     499                 :            : {
     500                 :          0 :     return false;
     501                 :            : }
     502                 :            : 
     503                 :          0 : bool XclExpCellBase::TryMerge( const XclExpCellBase& /*rCell*/ )
     504                 :            : {
     505                 :          0 :     return false;
     506                 :            : }
     507                 :            : 
     508                 :          0 : void XclExpCellBase::GetBlankXFIndexes( ScfUInt16Vec& /*rXFIndexes*/ ) const
     509                 :            : {
     510                 :            :     // default: do nothing
     511                 :          0 : }
     512                 :            : 
     513                 :          0 : void XclExpCellBase::RemoveUnusedBlankCells( const ScfUInt16Vec& /*rXFIndexes*/ )
     514                 :            : {
     515                 :            :     // default: do nothing
     516                 :          0 : }
     517                 :            : 
     518                 :            : // Single cell records ========================================================
     519                 :            : 
     520                 :          0 : XclExpSingleCellBase::XclExpSingleCellBase(
     521                 :            :         sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos, sal_uInt32 nXFId ) :
     522                 :            :     XclExpCellBase( nRecId, 2, rXclPos ),
     523                 :            :     maXFId( nXFId ),
     524         [ #  # ]:          0 :     mnContSize( nContSize )
     525                 :            : {
     526                 :          0 : }
     527                 :            : 
     528                 :          0 : XclExpSingleCellBase::XclExpSingleCellBase( const XclExpRoot& rRoot,
     529                 :            :         sal_uInt16 nRecId, sal_Size nContSize, const XclAddress& rXclPos,
     530                 :            :         const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uInt32 nForcedXFId ) :
     531                 :            :     XclExpCellBase( nRecId, 2, rXclPos ),
     532                 :            :     maXFId( nForcedXFId ),
     533         [ #  # ]:          0 :     mnContSize( nContSize )
     534                 :            : {
     535         [ #  # ]:          0 :     if( GetXFId() == EXC_XFID_NOTFOUND )
     536 [ #  # ][ #  # ]:          0 :         SetXFId( rRoot.GetXFBuffer().Insert( pPattern, nScript ) );
     537                 :          0 : }
     538                 :            : 
     539                 :          0 : sal_uInt16 XclExpSingleCellBase::GetLastXclCol() const
     540                 :            : {
     541                 :          0 :     return GetXclCol();
     542                 :            : }
     543                 :            : 
     544                 :          0 : sal_uInt32 XclExpSingleCellBase::GetFirstXFId() const
     545                 :            : {
     546                 :          0 :     return GetXFId();
     547                 :            : }
     548                 :            : 
     549                 :          0 : bool XclExpSingleCellBase::IsEmpty() const
     550                 :            : {
     551                 :          0 :     return false;
     552                 :            : }
     553                 :            : 
     554                 :          0 : void XclExpSingleCellBase::ConvertXFIndexes( const XclExpRoot& rRoot )
     555                 :            : {
     556                 :          0 :     maXFId.ConvertXFIndex( rRoot );
     557                 :          0 : }
     558                 :            : 
     559                 :          0 : void XclExpSingleCellBase::Save( XclExpStream& rStrm )
     560                 :            : {
     561                 :            :     OSL_ENSURE_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
     562                 :          0 :     AddRecSize( mnContSize );
     563                 :          0 :     XclExpCellBase::Save( rStrm );
     564                 :          0 : }
     565                 :            : 
     566                 :          0 : void XclExpSingleCellBase::WriteBody( XclExpStream& rStrm )
     567                 :            : {
     568                 :          0 :     rStrm << static_cast<sal_uInt16> (GetXclRow()) << GetXclCol() << maXFId.mnXFIndex;
     569                 :          0 :     WriteContents( rStrm );
     570                 :          0 : }
     571                 :            : 
     572                 :            : // ----------------------------------------------------------------------------
     573                 :            : 
     574                 :          8 : IMPL_FIXEDMEMPOOL_NEWDEL( XclExpNumberCell )
     575                 :            : 
     576                 :          0 : XclExpNumberCell::XclExpNumberCell(
     577                 :            :         const XclExpRoot& rRoot, const XclAddress& rXclPos,
     578                 :            :         const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, double fValue ) :
     579                 :            :     // #i41210# always use latin script for number cells - may look wrong for special number formats...
     580                 :            :     XclExpSingleCellBase( rRoot, EXC_ID3_NUMBER, 8, rXclPos, pPattern, ApiScriptType::LATIN, nForcedXFId ),
     581                 :          0 :     mfValue( fValue )
     582                 :            : {
     583                 :          0 : }
     584                 :            : 
     585                 :          0 : static OString lcl_GetStyleId( XclExpXmlStream& rStrm, sal_uInt32 nXFIndex )
     586                 :            : {
     587                 :          0 :     return OString::valueOf( rStrm.GetRoot().GetXFBuffer()
     588                 :          0 :             .GetXmlCellIndex( nXFIndex ) );
     589                 :            : }
     590                 :            : 
     591                 :          0 : static OString lcl_GetStyleId( XclExpXmlStream& rStrm, const XclExpCellBase& rCell )
     592                 :            : {
     593                 :          0 :     sal_uInt32 nXFId    = rCell.GetFirstXFId();
     594                 :          0 :     sal_uInt16 nXFIndex = rStrm.GetRoot().GetXFBuffer().GetXFIndex( nXFId );
     595                 :          0 :     return lcl_GetStyleId( rStrm, nXFIndex );
     596                 :            : }
     597                 :            : 
     598                 :          0 : void XclExpNumberCell::SaveXml( XclExpXmlStream& rStrm )
     599                 :            : {
     600                 :          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     601                 :            :     rWorksheet->startElement( XML_c,
     602                 :          0 :             XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
     603                 :            :             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
     604                 :            :             XML_t,      "n",
     605                 :            :             // OOXTODO: XML_cm, XML_vm, XML_ph
     606 [ #  # ][ #  # ]:          0 :             FSEND );
     607                 :          0 :     rWorksheet->startElement( XML_v, FSEND );
     608                 :          0 :     rWorksheet->write( mfValue );
     609                 :          0 :     rWorksheet->endElement( XML_v );
     610                 :          0 :     rWorksheet->endElement( XML_c );
     611                 :          0 : }
     612                 :            : 
     613                 :          0 : void XclExpNumberCell::WriteContents( XclExpStream& rStrm )
     614                 :            : {
     615                 :          0 :     rStrm << mfValue;
     616                 :          0 : }
     617                 :            : 
     618                 :            : // ----------------------------------------------------------------------------
     619                 :            : 
     620                 :          8 : IMPL_FIXEDMEMPOOL_NEWDEL( XclExpBooleanCell )
     621                 :            : 
     622                 :          0 : XclExpBooleanCell::XclExpBooleanCell(
     623                 :            :         const XclExpRoot rRoot, const XclAddress& rXclPos,
     624                 :            :         const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, bool bValue ) :
     625                 :            :     // #i41210# always use latin script for boolean cells
     626                 :            :     XclExpSingleCellBase( rRoot, EXC_ID3_BOOLERR, 2, rXclPos, pPattern, ApiScriptType::LATIN, nForcedXFId ),
     627                 :          0 :     mbValue( bValue )
     628                 :            : {
     629                 :          0 : }
     630                 :            : 
     631                 :          0 : void XclExpBooleanCell::SaveXml( XclExpXmlStream& rStrm )
     632                 :            : {
     633                 :          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     634                 :            :     rWorksheet->startElement( XML_c,
     635                 :          0 :             XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
     636                 :            :             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
     637                 :            :             XML_t,      "b",
     638                 :            :             // OOXTODO: XML_cm, XML_vm, XML_ph
     639 [ #  # ][ #  # ]:          0 :             FSEND );
     640                 :          0 :     rWorksheet->startElement( XML_v, FSEND );
     641         [ #  # ]:          0 :     rWorksheet->write( mbValue ? "1" : "0" );
     642                 :          0 :     rWorksheet->endElement( XML_v );
     643                 :          0 :     rWorksheet->endElement( XML_c );
     644                 :          0 : }
     645                 :            : 
     646                 :          0 : void XclExpBooleanCell::WriteContents( XclExpStream& rStrm )
     647                 :            : {
     648         [ #  # ]:          0 :     rStrm << sal_uInt16( mbValue ? 1 : 0 ) << EXC_BOOLERR_BOOL;
     649                 :          0 : }
     650                 :            : 
     651                 :          8 : IMPL_FIXEDMEMPOOL_NEWDEL( XclExpLabelCell )
     652                 :            : 
     653                 :          0 : XclExpLabelCell::XclExpLabelCell(
     654                 :            :         const XclExpRoot& rRoot, const XclAddress& rXclPos,
     655                 :            :         const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, const ScStringCell& rCell ) :
     656         [ #  # ]:          0 :     XclExpSingleCellBase( EXC_ID3_LABEL, 0, rXclPos, nForcedXFId )
     657                 :            : {
     658         [ #  # ]:          0 :     sal_uInt16 nMaxLen = (rRoot.GetBiff() == EXC_BIFF8) ? EXC_STR_MAXLEN : EXC_LABEL_MAXLEN;
     659         [ #  # ]:          0 :     XclExpStringRef xText = XclExpStringHelper::CreateCellString( rRoot, rCell, pPattern, EXC_STR_DEFAULT, nMaxLen );
     660 [ #  # ][ #  # ]:          0 :     Init( rRoot, pPattern, xText );
         [ #  # ][ #  # ]
     661                 :          0 : }
     662                 :            : 
     663                 :          0 : XclExpLabelCell::XclExpLabelCell(
     664                 :            :         const XclExpRoot& rRoot, const XclAddress& rXclPos,
     665                 :            :         const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
     666                 :            :         const ScEditCell& rCell, XclExpHyperlinkHelper& rLinkHelper ) :
     667         [ #  # ]:          0 :     XclExpSingleCellBase( EXC_ID3_LABEL, 0, rXclPos, nForcedXFId )
     668                 :            : {
     669         [ #  # ]:          0 :     sal_uInt16 nMaxLen = (rRoot.GetBiff() == EXC_BIFF8) ? EXC_STR_MAXLEN : EXC_LABEL_MAXLEN;
     670         [ #  # ]:          0 :     XclExpStringRef xText = XclExpStringHelper::CreateCellString( rRoot, rCell, pPattern, rLinkHelper, EXC_STR_DEFAULT, nMaxLen );
     671 [ #  # ][ #  # ]:          0 :     Init( rRoot, pPattern, xText );
         [ #  # ][ #  # ]
     672                 :          0 : }
     673                 :            : 
     674                 :          0 : bool XclExpLabelCell::IsMultiLineText() const
     675                 :            : {
     676 [ #  # ][ #  # ]:          0 :     return mbLineBreak || mxText->IsWrapped();
     677                 :            : }
     678                 :            : 
     679                 :          0 : void XclExpLabelCell::Init( const XclExpRoot& rRoot,
     680                 :            :         const ScPatternAttr* pPattern, XclExpStringRef xText )
     681                 :            : {
     682                 :            :     OSL_ENSURE( xText && xText->Len(), "XclExpLabelCell::XclExpLabelCell - empty string passed" );
     683                 :          0 :     mxText = xText;
     684                 :          0 :     mnSstIndex = 0;
     685                 :            : 
     686                 :            :     // create the cell format
     687                 :          0 :     sal_uInt16 nXclFont = mxText->RemoveLeadingFont();
     688         [ #  # ]:          0 :     if( GetXFId() == EXC_XFID_NOTFOUND )
     689                 :            :     {
     690                 :            :         OSL_ENSURE( nXclFont != EXC_FONT_NOTFOUND, "XclExpLabelCell::Init - leading font not found" );
     691                 :          0 :         bool bForceLineBreak = mxText->IsWrapped();
     692                 :          0 :         SetXFId( rRoot.GetXFBuffer().InsertWithFont( pPattern, ApiScriptType::WEAK, nXclFont, bForceLineBreak ) );
     693                 :            :     }
     694                 :            : 
     695                 :            :     // get auto-wrap attribute from cell format
     696                 :          0 :     const XclExpXF* pXF = rRoot.GetXFBuffer().GetXFById( GetXFId() );
     697 [ #  # ][ #  # ]:          0 :     mbLineBreak = pXF && pXF->GetAlignmentData().mbLineBreak;
     698                 :            : 
     699                 :            :     // initialize the record contents
     700      [ #  #  # ]:          0 :     switch( rRoot.GetBiff() )
     701                 :            :     {
     702                 :            :         case EXC_BIFF5:
     703                 :            :             // BIFF5-BIFF7: create a LABEL or RSTRING record
     704                 :            :             OSL_ENSURE( mxText->Len() <= EXC_LABEL_MAXLEN, "XclExpLabelCell::XclExpLabelCell - string too long" );
     705                 :          0 :             SetContSize( mxText->GetSize() );
     706                 :            :             // formatted string is exported in an RSTRING record
     707         [ #  # ]:          0 :             if( mxText->IsRich() )
     708                 :            :             {
     709                 :            :                 OSL_ENSURE( mxText->GetFormatsCount() <= EXC_LABEL_MAXLEN, "XclExpLabelCell::WriteContents - too many formats" );
     710                 :          0 :                 mxText->LimitFormatCount( EXC_LABEL_MAXLEN );
     711                 :          0 :                 SetRecId( EXC_ID_RSTRING );
     712                 :          0 :                 SetContSize( GetContSize() + 1 + 2 * mxText->GetFormatsCount() );
     713                 :            :             }
     714                 :          0 :         break;
     715                 :            :         case EXC_BIFF8:
     716                 :            :             // BIFF8+: create a LABELSST record
     717 [ #  # ][ #  # ]:          0 :             mnSstIndex = rRoot.GetSst().Insert( xText );
     718                 :          0 :             SetRecId( EXC_ID_LABELSST );
     719                 :          0 :             SetContSize( 4 );
     720                 :          0 :         break;
     721                 :            :         default:    DBG_ERROR_BIFF();
     722                 :            :     }
     723                 :          0 : }
     724                 :            : 
     725                 :          0 : void XclExpLabelCell::SaveXml( XclExpXmlStream& rStrm )
     726                 :            : {
     727                 :          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     728                 :            :     rWorksheet->startElement( XML_c,
     729                 :          0 :             XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
     730                 :            :             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
     731                 :            :             XML_t,      "s",
     732                 :            :             // OOXTODO: XML_cm, XML_vm, XML_ph
     733 [ #  # ][ #  # ]:          0 :             FSEND );
     734                 :          0 :     rWorksheet->startElement( XML_v, FSEND );
     735                 :          0 :     rWorksheet->write( (sal_Int32) mnSstIndex );
     736                 :          0 :     rWorksheet->endElement( XML_v );
     737                 :          0 :     rWorksheet->endElement( XML_c );
     738                 :          0 : }
     739                 :            : 
     740                 :          0 : void XclExpLabelCell::WriteContents( XclExpStream& rStrm )
     741                 :            : {
     742      [ #  #  # ]:          0 :     switch( rStrm.GetRoot().GetBiff() )
     743                 :            :     {
     744                 :            :         case EXC_BIFF5:
     745                 :          0 :             rStrm << *mxText;
     746         [ #  # ]:          0 :             if( mxText->IsRich() )
     747                 :            :             {
     748                 :          0 :                 rStrm << static_cast< sal_uInt8 >( mxText->GetFormatsCount() );
     749                 :          0 :                 mxText->WriteFormats( rStrm );
     750                 :            :             }
     751                 :          0 :         break;
     752                 :            :         case EXC_BIFF8:
     753                 :          0 :             rStrm << mnSstIndex;
     754                 :          0 :         break;
     755                 :            :         default:    DBG_ERROR_BIFF();
     756                 :            :     }
     757                 :          0 : }
     758                 :            : 
     759                 :            : // ----------------------------------------------------------------------------
     760                 :            : 
     761                 :          8 : IMPL_FIXEDMEMPOOL_NEWDEL( XclExpFormulaCell )
     762                 :            : 
     763                 :          0 : XclExpFormulaCell::XclExpFormulaCell(
     764                 :            :         const XclExpRoot& rRoot, const XclAddress& rXclPos,
     765                 :            :         const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId,
     766                 :            :         const ScFormulaCell& rScFmlaCell,
     767                 :            :         XclExpArrayBuffer& rArrayBfr,
     768                 :            :         XclExpShrfmlaBuffer& rShrfmlaBfr,
     769                 :            :         XclExpTableopBuffer& rTableopBfr ) :
     770                 :            :     XclExpSingleCellBase( EXC_ID2_FORMULA, 0, rXclPos, nForcedXFId ),
     771 [ #  # ][ #  # ]:          0 :     mrScFmlaCell( const_cast< ScFormulaCell& >( rScFmlaCell ) )
                 [ #  # ]
     772                 :            : {
     773                 :            :     // *** Find result number format overwriting cell number format *** -------
     774                 :            : 
     775         [ #  # ]:          0 :     if( GetXFId() == EXC_XFID_NOTFOUND )
     776                 :            :     {
     777         [ #  # ]:          0 :         SvNumberFormatter& rFormatter = rRoot.GetFormatter();
     778         [ #  # ]:          0 :         XclExpNumFmtBuffer& rNumFmtBfr = rRoot.GetNumFmtBuffer();
     779                 :            : 
     780                 :            :         // current cell number format
     781                 :            :         sal_uLong nScNumFmt = pPattern ?
     782         [ #  # ]:          0 :             GETITEMVALUE( pPattern->GetItemSet(), SfxUInt32Item, ATTR_VALUE_FORMAT, sal_uLong ) :
     783         [ #  # ]:          0 :             rNumFmtBfr.GetStandardFormat();
     784                 :            : 
     785                 :            :         // alternative number format passed to XF buffer
     786                 :          0 :         sal_uLong nAltScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND;
     787                 :            :         /*  Xcl doesn't know Boolean number formats, we write
     788                 :            :             "TRUE";"FALSE" (language dependent). Don't do it for automatic
     789                 :            :             formula formats, because Excel gets them right. */
     790                 :            :         /*  #i8640# Don't set text format, if we have string results. */
     791                 :          0 :         short nFormatType = mrScFmlaCell.GetFormatType();
     792 [ #  # ][ #  # ]:          0 :         if( ((nScNumFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0) &&
                 [ #  # ]
     793                 :            :                 (nFormatType != NUMBERFORMAT_LOGICAL) &&
     794                 :            :                 (nFormatType != NUMBERFORMAT_TEXT) )
     795         [ #  # ]:          0 :             nAltScNumFmt = mrScFmlaCell.GetStandardFormat( rFormatter, nScNumFmt );
     796                 :            :         /*  If cell number format is Boolean and automatic formula
     797                 :            :             format is Boolean don't write that ugly special format. */
     798 [ #  # ][ #  # ]:          0 :         else if( (nFormatType == NUMBERFORMAT_LOGICAL) &&
                 [ #  # ]
     799         [ #  # ]:          0 :                 (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) )
     800                 :          0 :             nAltScNumFmt = rNumFmtBfr.GetStandardFormat();
     801                 :            : 
     802                 :            :         // #i41420# find script type according to result type (always latin for numeric results)
     803                 :          0 :         sal_Int16 nScript = ApiScriptType::LATIN;
     804                 :          0 :         bool bForceLineBreak = false;
     805         [ #  # ]:          0 :         if( nFormatType == NUMBERFORMAT_TEXT )
     806                 :            :         {
     807 [ #  # ][ #  # ]:          0 :             String aResult = mrScFmlaCell.GetString();
     808         [ #  # ]:          0 :             bForceLineBreak = mrScFmlaCell.IsMultilineResult();
     809 [ #  # ][ #  # ]:          0 :             nScript = XclExpStringHelper::GetLeadingScriptType( rRoot, aResult );
     810                 :            :         }
     811 [ #  # ][ #  # ]:          0 :         SetXFId( rRoot.GetXFBuffer().InsertWithNumFmt( pPattern, nScript, nAltScNumFmt, bForceLineBreak ) );
     812                 :            :     }
     813                 :            : 
     814                 :            :     // *** Convert the formula token array *** --------------------------------
     815                 :            : 
     816                 :          0 :     ScAddress aScPos( static_cast< SCCOL >( rXclPos.mnCol ), static_cast< SCROW >( rXclPos.mnRow ), rRoot.GetCurrScTab() );
     817                 :          0 :     const ScTokenArray& rScTokArr = *mrScFmlaCell.GetCode();
     818                 :            : 
     819                 :            :     // first try to create multiple operations
     820 [ #  # ][ #  # ]:          0 :     mxAddRec = rTableopBfr.CreateOrExtendTableop( rScTokArr, aScPos );
                 [ #  # ]
     821                 :            : 
     822                 :            :     // no multiple operation found - try to create matrix formula
     823         [ #  # ]:          0 :     if( !mxAddRec ) switch( static_cast< ScMatrixMode >( mrScFmlaCell.GetMatrixFlag() ) )
              [ #  #  # ]
     824                 :            :     {
     825                 :            :         case MM_FORMULA:
     826                 :            :         {
     827                 :            :             // origin of the matrix - find the used matrix range
     828                 :            :             SCCOL nMatWidth;
     829                 :            :             SCROW nMatHeight;
     830         [ #  # ]:          0 :             mrScFmlaCell.GetMatColsRows( nMatWidth, nMatHeight );
     831                 :            :             OSL_ENSURE( nMatWidth && nMatHeight, "XclExpFormulaCell::XclExpFormulaCell - empty matrix" );
     832                 :          0 :             ScRange aMatScRange( aScPos );
     833                 :          0 :             ScAddress& rMatEnd = aMatScRange.aEnd;
     834         [ #  # ]:          0 :             rMatEnd.IncCol( static_cast< SCsCOL >( nMatWidth - 1 ) );
     835         [ #  # ]:          0 :             rMatEnd.IncRow( static_cast< SCsROW >( nMatHeight - 1 ) );
     836                 :            :             // reduce to valid range (range keeps valid, because start position IS valid)
     837 [ #  # ][ #  # ]:          0 :             rRoot.GetAddressConverter().ValidateRange( aMatScRange, true );
     838                 :            :             // create the ARRAY record
     839 [ #  # ][ #  # ]:          0 :             mxAddRec = rArrayBfr.CreateArray( rScTokArr, aMatScRange );
                 [ #  # ]
     840                 :            :         }
     841                 :          0 :         break;
     842                 :            :         case MM_REFERENCE:
     843                 :            :         {
     844                 :            :             // other formula cell covered by a matrix - find the ARRAY record
     845 [ #  # ][ #  # ]:          0 :             mxAddRec = rArrayBfr.FindArray( rScTokArr );
                 [ #  # ]
     846                 :            :             // should always be found, if Calc document is not broken
     847                 :            :             OSL_ENSURE( mxAddRec, "XclExpFormulaCell::XclExpFormulaCell - no matrix found" );
     848                 :            :         }
     849                 :          0 :         break;
     850                 :            :         default:;
     851                 :            :     }
     852                 :            : 
     853                 :            :     // no matrix found - try to create shared formula
     854         [ #  # ]:          0 :     if( !mxAddRec )
     855 [ #  # ][ #  # ]:          0 :         mxAddRec = rShrfmlaBfr.CreateOrExtendShrfmla( rScTokArr, aScPos );
                 [ #  # ]
     856                 :            : 
     857                 :            :     // no shared formula found - create a simple cell formula
     858         [ #  # ]:          0 :     if( !mxAddRec )
     859 [ #  # ][ #  # ]:          0 :         mxTokArr = rRoot.GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CELL, rScTokArr, &aScPos );
         [ #  # ][ #  # ]
     860                 :          0 : }
     861                 :            : 
     862                 :          0 : void XclExpFormulaCell::Save( XclExpStream& rStrm )
     863                 :            : {
     864                 :            :     // create token array for FORMULA cells with additional record
     865         [ #  # ]:          0 :     if( mxAddRec )
     866         [ #  # ]:          0 :         mxTokArr = mxAddRec->CreateCellTokenArray( rStrm.GetRoot() );
     867                 :            : 
     868                 :            :     // FORMULA record itself
     869                 :            :     OSL_ENSURE( mxTokArr, "XclExpFormulaCell::Save - missing token array" );
     870         [ #  # ]:          0 :     if( !mxTokArr )
     871         [ #  # ]:          0 :         mxTokArr = rStrm.GetRoot().GetFormulaCompiler().CreateErrorFormula( EXC_ERR_NA );
     872                 :          0 :     SetContSize( 16 + mxTokArr->GetSize() );
     873                 :          0 :     XclExpSingleCellBase::Save( rStrm );
     874                 :            : 
     875                 :            :     // additional record (ARRAY, SHRFMLA, or TABLEOP), only for first FORMULA record
     876 [ #  # ][ #  # ]:          0 :     if( mxAddRec && mxAddRec->IsBasePos( GetXclCol(), GetXclRow() ) )
                 [ #  # ]
     877                 :          0 :         mxAddRec->Save( rStrm );
     878                 :            : 
     879                 :            :     // STRING record for string result
     880         [ #  # ]:          0 :     if( mxStringRec )
     881                 :          0 :         mxStringRec->Save( rStrm );
     882                 :          0 : }
     883                 :            : 
     884                 :          0 : void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm )
     885                 :            : {
     886                 :          0 :     const char* sType = NULL;
     887                 :          0 :     OUString    sValue;
     888                 :            : 
     889         [ #  # ]:          0 :     XclXmlUtils::GetFormulaTypeAndValue( mrScFmlaCell, sType, sValue );
     890         [ #  # ]:          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
     891                 :            :     rWorksheet->startElement( XML_c,
     892                 :          0 :             XML_r,      XclXmlUtils::ToOString( GetXclPos() ).getStr(),
     893                 :            :             XML_s,      lcl_GetStyleId( rStrm, *this ).getStr(),
     894                 :            :             XML_t,      sType,
     895                 :            :             // OOXTODO: XML_cm, XML_vm, XML_ph
     896 [ #  # ][ #  # ]:          0 :             FSEND );
                 [ #  # ]
     897                 :            : 
     898                 :            :     rWorksheet->startElement( XML_f,
     899                 :            :             // OOXTODO: XML_t,      ST_CellFormulaType
     900         [ #  # ]:          0 :             XML_aca,    XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || (mxAddRec && mxAddRec->IsVolatile()) ),
     901                 :            :             // OOXTODO: XML_ref,    ST_Ref
     902                 :            :             // OOXTODO: XML_dt2D,   bool
     903                 :            :             // OOXTODO: XML_dtr,    bool
     904                 :            :             // OOXTODO: XML_del1,   bool
     905                 :            :             // OOXTODO: XML_del2,   bool
     906                 :            :             // OOXTODO: XML_r1,     ST_CellRef
     907                 :            :             // OOXTODO: XML_r2,     ST_CellRef
     908                 :            :             // OOXTODO: XML_ca,     bool
     909                 :            :             // OOXTODO: XML_si,     uint
     910                 :            :             // OOXTODO: XML_bx      bool
     911 [ #  # ][ #  # ]:          0 :             FSEND );
         [ #  # ][ #  #  
             #  #  #  # ]
     912 [ #  # ][ #  # ]:          0 :     rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *mrScFmlaCell.GetDocument(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode() ) );
     913         [ #  # ]:          0 :     rWorksheet->endElement( XML_f );
     914         [ #  # ]:          0 :     if( strcmp( sType, "inlineStr" ) == 0 )
     915                 :            :     {
     916         [ #  # ]:          0 :         rWorksheet->startElement( XML_is, FSEND );
     917         [ #  # ]:          0 :         rWorksheet->startElement( XML_t, FSEND );
     918         [ #  # ]:          0 :         rWorksheet->writeEscaped( sValue );
     919         [ #  # ]:          0 :         rWorksheet->endElement( XML_t );
     920         [ #  # ]:          0 :         rWorksheet->endElement( XML_is );
     921                 :            :     }
     922                 :            :     else
     923                 :            :     {
     924         [ #  # ]:          0 :         rWorksheet->startElement( XML_v, FSEND );
     925         [ #  # ]:          0 :         rWorksheet->writeEscaped( sValue );
     926         [ #  # ]:          0 :         rWorksheet->endElement( XML_v );
     927                 :            :     }
     928         [ #  # ]:          0 :     rWorksheet->endElement( XML_c );
     929                 :          0 : }
     930                 :            : 
     931                 :          0 : void XclExpFormulaCell::WriteContents( XclExpStream& rStrm )
     932                 :            : {
     933                 :            :     // result of the formula
     934   [ #  #  #  # ]:          0 :     switch( mrScFmlaCell.GetFormatType() )
     935                 :            :     {
     936                 :            :         case NUMBERFORMAT_NUMBER:
     937                 :            :         {
     938                 :            :             // either value or error code
     939         [ #  # ]:          0 :             sal_uInt16 nScErrCode = mrScFmlaCell.GetErrCode();
     940         [ #  # ]:          0 :             if( nScErrCode )
     941 [ #  # ][ #  # ]:          0 :                 rStrm << EXC_FORMULA_RES_ERROR << sal_uInt8( 0 )
     942 [ #  # ][ #  # ]:          0 :                       << XclTools::GetXclErrorCode( nScErrCode )
     943 [ #  # ][ #  # ]:          0 :                       << sal_uInt8( 0 ) << sal_uInt16( 0 )
     944         [ #  # ]:          0 :                       << sal_uInt16( 0xFFFF );
     945                 :            :             else
     946 [ #  # ][ #  # ]:          0 :                 rStrm << mrScFmlaCell.GetValue();
     947                 :            :         }
     948                 :          0 :         break;
     949                 :            : 
     950                 :            :         case NUMBERFORMAT_TEXT:
     951                 :            :         {
     952 [ #  # ][ #  # ]:          0 :             String aResult = mrScFmlaCell.GetString();
     953 [ #  # ][ #  # ]:          0 :             if( aResult.Len() || (rStrm.GetRoot().GetBiff() <= EXC_BIFF5) )
                 [ #  # ]
     954                 :            :             {
     955         [ #  # ]:          0 :                 rStrm << EXC_FORMULA_RES_STRING;
     956 [ #  # ][ #  # ]:          0 :                 mxStringRec.reset( new XclExpStringRec( rStrm.GetRoot(), aResult ) );
                 [ #  # ]
     957                 :            :             }
     958                 :            :             else
     959         [ #  # ]:          0 :                 rStrm << EXC_FORMULA_RES_EMPTY;     // BIFF8 only
     960 [ #  # ][ #  # ]:          0 :             rStrm << sal_uInt8( 0 ) << sal_uInt32( 0 ) << sal_uInt16( 0xFFFF );
         [ #  # ][ #  # ]
     961                 :            :         }
     962                 :          0 :         break;
     963                 :            : 
     964                 :            :         case NUMBERFORMAT_LOGICAL:
     965                 :            :         {
     966         [ #  # ]:          0 :             sal_uInt8 nXclValue = (mrScFmlaCell.GetValue() == 0.0) ? 0 : 1;
     967 [ #  # ][ #  # ]:          0 :             rStrm << EXC_FORMULA_RES_BOOL << sal_uInt8( 0 )
     968 [ #  # ][ #  # ]:          0 :                   << nXclValue << sal_uInt8( 0 ) << sal_uInt16( 0 )
                 [ #  # ]
     969         [ #  # ]:          0 :                   << sal_uInt16( 0xFFFF );
     970                 :            :         }
     971                 :          0 :         break;
     972                 :            : 
     973                 :            :         default:
     974 [ #  # ][ #  # ]:          0 :             rStrm << mrScFmlaCell.GetValue();
     975                 :            :     }
     976                 :            : 
     977                 :            :     // flags and formula token array
     978                 :          0 :     sal_uInt16 nFlags = EXC_FORMULA_DEFAULTFLAGS;
     979 [ #  # ][ #  # ]:          0 :     ::set_flag( nFlags, EXC_FORMULA_RECALC_ALWAYS, mxTokArr->IsVolatile() || (mxAddRec && mxAddRec->IsVolatile()) );
         [ #  # ][ #  # ]
     980 [ #  # ][ #  # ]:          0 :     ::set_flag( nFlags, EXC_FORMULA_SHARED, mxAddRec && (mxAddRec->GetRecId() == EXC_ID_SHRFMLA) );
     981 [ #  # ][ #  # ]:          0 :     rStrm << nFlags << sal_uInt32( 0 ) << *mxTokArr;
                 [ #  # ]
     982                 :          0 : }
     983                 :            : 
     984                 :            : // Multiple cell records ======================================================
     985                 :            : 
     986                 :          0 : XclExpMultiCellBase::XclExpMultiCellBase(
     987                 :            :         sal_uInt16 nRecId, sal_uInt16 nMulRecId, sal_Size nContSize, const XclAddress& rXclPos ) :
     988                 :            :     XclExpCellBase( nRecId, 0, rXclPos ),
     989                 :            :     mnMulRecId( nMulRecId ),
     990         [ #  # ]:          0 :     mnContSize( nContSize )
     991                 :            : {
     992                 :          0 : }
     993                 :            : 
     994                 :          0 : sal_uInt16 XclExpMultiCellBase::GetLastXclCol() const
     995                 :            : {
     996                 :          0 :     return GetXclCol() + GetCellCount() - 1;
     997                 :            : }
     998                 :            : 
     999                 :          0 : sal_uInt32 XclExpMultiCellBase::GetFirstXFId() const
    1000                 :            : {
    1001         [ #  # ]:          0 :     return maXFIds.empty() ? XclExpXFBuffer::GetDefCellXFId() : maXFIds.front().mnXFId;
    1002                 :            : }
    1003                 :            : 
    1004                 :          0 : bool XclExpMultiCellBase::IsEmpty() const
    1005                 :            : {
    1006                 :          0 :     return maXFIds.empty();
    1007                 :            : }
    1008                 :            : 
    1009                 :          0 : void XclExpMultiCellBase::ConvertXFIndexes( const XclExpRoot& rRoot )
    1010                 :            : {
    1011 [ #  # ][ #  # ]:          0 :     for( XclExpMultiXFIdDeq::iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
                 [ #  # ]
    1012         [ #  # ]:          0 :         aIt->ConvertXFIndex( rRoot );
    1013                 :          0 : }
    1014                 :            : 
    1015                 :          0 : void XclExpMultiCellBase::Save( XclExpStream& rStrm )
    1016                 :            : {
    1017                 :            :     OSL_ENSURE_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
    1018                 :            : 
    1019                 :          0 :     XclExpMultiXFIdDeq::const_iterator aEnd = maXFIds.end();
    1020                 :          0 :     XclExpMultiXFIdDeq::const_iterator aRangeBeg = maXFIds.begin();
    1021                 :          0 :     XclExpMultiXFIdDeq::const_iterator aRangeEnd = aRangeBeg;
    1022                 :          0 :     sal_uInt16 nBegXclCol = GetXclCol();
    1023                 :          0 :     sal_uInt16 nEndXclCol = nBegXclCol;
    1024                 :            : 
    1025 [ #  # ][ #  # ]:          0 :     while( aRangeEnd != aEnd )
    1026                 :            :     {
    1027                 :            :         // find begin of next used XF range
    1028                 :          0 :         aRangeBeg = aRangeEnd;
    1029                 :          0 :         nBegXclCol = nEndXclCol;
    1030 [ #  # ][ #  # ]:          0 :         while( (aRangeBeg != aEnd) && (aRangeBeg->mnXFIndex == EXC_XF_NOTFOUND) )
         [ #  # ][ #  # ]
    1031                 :            :         {
    1032                 :          0 :             nBegXclCol = nBegXclCol + aRangeBeg->mnCount;
    1033         [ #  # ]:          0 :             ++aRangeBeg;
    1034                 :            :         }
    1035                 :            :         // find end of next used XF range
    1036                 :          0 :         aRangeEnd = aRangeBeg;
    1037                 :          0 :         nEndXclCol = nBegXclCol;
    1038 [ #  # ][ #  # ]:          0 :         while( (aRangeEnd != aEnd) && (aRangeEnd->mnXFIndex != EXC_XF_NOTFOUND) )
         [ #  # ][ #  # ]
    1039                 :            :         {
    1040                 :          0 :             nEndXclCol = nEndXclCol + aRangeEnd->mnCount;
    1041         [ #  # ]:          0 :             ++aRangeEnd;
    1042                 :            :         }
    1043                 :            : 
    1044                 :            :         // export this range as a record
    1045 [ #  # ][ #  # ]:          0 :         if( aRangeBeg != aRangeEnd )
    1046                 :            :         {
    1047                 :          0 :             sal_uInt16 nCount = nEndXclCol - nBegXclCol;
    1048                 :          0 :             bool bIsMulti = nCount > 1;
    1049                 :          0 :             sal_Size nTotalSize = GetRecSize() + (2 + mnContSize) * nCount;
    1050         [ #  # ]:          0 :             if( bIsMulti ) nTotalSize += 2;
    1051                 :            : 
    1052 [ #  # ][ #  # ]:          0 :             rStrm.StartRecord( bIsMulti ? mnMulRecId : GetRecId(), nTotalSize );
    1053 [ #  # ][ #  # ]:          0 :             rStrm << static_cast<sal_uInt16> (GetXclRow()) << nBegXclCol;
    1054                 :            : 
    1055                 :          0 :             sal_uInt16 nRelCol = nBegXclCol - GetXclCol();
    1056 [ #  # ][ #  # ]:          0 :             for( XclExpMultiXFIdDeq::const_iterator aIt = aRangeBeg; aIt != aRangeEnd; ++aIt )
                 [ #  # ]
    1057                 :            :             {
    1058         [ #  # ]:          0 :                 for( sal_uInt16 nIdx = 0; nIdx < aIt->mnCount; ++nIdx )
    1059                 :            :                 {
    1060         [ #  # ]:          0 :                     rStrm << aIt->mnXFIndex;
    1061         [ #  # ]:          0 :                     WriteContents( rStrm, nRelCol );
    1062                 :          0 :                     ++nRelCol;
    1063                 :            :                 }
    1064                 :            :             }
    1065         [ #  # ]:          0 :             if( bIsMulti )
    1066         [ #  # ]:          0 :                 rStrm << static_cast< sal_uInt16 >( nEndXclCol - 1 );
    1067         [ #  # ]:          0 :             rStrm.EndRecord();
    1068                 :            :         }
    1069                 :            :     }
    1070                 :          0 : }
    1071                 :            : 
    1072                 :          0 : void XclExpMultiCellBase::SaveXml( XclExpXmlStream& rStrm )
    1073                 :            : {
    1074                 :          0 :     XclExpMultiXFIdDeq::const_iterator aEnd = maXFIds.end();
    1075                 :          0 :     XclExpMultiXFIdDeq::const_iterator aRangeBeg = maXFIds.begin();
    1076                 :          0 :     XclExpMultiXFIdDeq::const_iterator aRangeEnd = aRangeBeg;
    1077                 :          0 :     sal_uInt16 nBegXclCol = GetXclCol();
    1078                 :          0 :     sal_uInt16 nEndXclCol = nBegXclCol;
    1079                 :            : 
    1080 [ #  # ][ #  # ]:          0 :     while( aRangeEnd != aEnd )
    1081                 :            :     {
    1082                 :            :         // find begin of next used XF range
    1083                 :          0 :         aRangeBeg = aRangeEnd;
    1084                 :          0 :         nBegXclCol = nEndXclCol;
    1085 [ #  # ][ #  # ]:          0 :         while( (aRangeBeg != aEnd) && (aRangeBeg->mnXFIndex == EXC_XF_NOTFOUND) )
         [ #  # ][ #  # ]
    1086                 :            :         {
    1087                 :          0 :             nBegXclCol = nBegXclCol + aRangeBeg->mnCount;
    1088         [ #  # ]:          0 :             ++aRangeBeg;
    1089                 :            :         }
    1090                 :            :         // find end of next used XF range
    1091                 :          0 :         aRangeEnd = aRangeBeg;
    1092                 :          0 :         nEndXclCol = nBegXclCol;
    1093 [ #  # ][ #  # ]:          0 :         while( (aRangeEnd != aEnd) && (aRangeEnd->mnXFIndex != EXC_XF_NOTFOUND) )
         [ #  # ][ #  # ]
    1094                 :            :         {
    1095                 :          0 :             nEndXclCol = nEndXclCol + aRangeEnd->mnCount;
    1096         [ #  # ]:          0 :             ++aRangeEnd;
    1097                 :            :         }
    1098                 :            : 
    1099                 :            :         // export this range as a record
    1100 [ #  # ][ #  # ]:          0 :         if( aRangeBeg != aRangeEnd )
    1101                 :            :         {
    1102                 :          0 :             sal_uInt16 nRelColIdx = nBegXclCol - GetXclCol();
    1103                 :          0 :             sal_Int32  nRelCol    = 0;
    1104 [ #  # ][ #  # ]:          0 :             for( XclExpMultiXFIdDeq::const_iterator aIt = aRangeBeg; aIt != aRangeEnd; ++aIt )
                 [ #  # ]
    1105                 :            :             {
    1106         [ #  # ]:          0 :                 for( sal_uInt16 nIdx = 0; nIdx < aIt->mnCount; ++nIdx )
    1107                 :            :                 {
    1108                 :            :                     WriteXmlContents(
    1109                 :            :                             rStrm,
    1110                 :            :                             XclAddress( static_cast<sal_uInt16>(nBegXclCol + nRelCol), GetXclRow() ),
    1111                 :          0 :                             aIt->mnXFIndex,
    1112         [ #  # ]:          0 :                             nRelColIdx );
    1113                 :          0 :                     ++nRelCol;
    1114                 :          0 :                     ++nRelColIdx;
    1115                 :            :                 }
    1116                 :            :             }
    1117                 :            :         }
    1118                 :            :     }
    1119                 :          0 : }
    1120                 :            : 
    1121                 :          0 : sal_uInt16 XclExpMultiCellBase::GetCellCount() const
    1122                 :            : {
    1123                 :          0 :     sal_uInt16 nCount = 0;
    1124 [ #  # ][ #  # ]:          0 :     for( XclExpMultiXFIdDeq::const_iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
                 [ #  # ]
    1125                 :          0 :         nCount = nCount + aIt->mnCount;
    1126                 :          0 :     return nCount;
    1127                 :            : }
    1128                 :            : 
    1129                 :          0 : void XclExpMultiCellBase::AppendXFId( const XclExpMultiXFId& rXFId )
    1130                 :            : {
    1131 [ #  # ][ #  # ]:          0 :     if( maXFIds.empty() || (maXFIds.back().mnXFId != rXFId.mnXFId) )
                 [ #  # ]
    1132                 :          0 :         maXFIds.push_back( rXFId );
    1133                 :            :     else
    1134                 :          0 :         maXFIds.back().mnCount = maXFIds.back().mnCount + rXFId.mnCount;
    1135                 :          0 : }
    1136                 :            : 
    1137                 :          0 : void XclExpMultiCellBase::AppendXFId( const XclExpRoot& rRoot,
    1138                 :            :         const ScPatternAttr* pPattern, sal_uInt16 nScript, sal_uInt32 nForcedXFId, sal_uInt16 nCount )
    1139                 :            : {
    1140                 :            :     sal_uInt32 nXFId = (nForcedXFId == EXC_XFID_NOTFOUND) ?
    1141         [ #  # ]:          0 :         rRoot.GetXFBuffer().Insert( pPattern, nScript ) : nForcedXFId;
    1142         [ #  # ]:          0 :     AppendXFId( XclExpMultiXFId( nXFId, nCount ) );
    1143                 :          0 : }
    1144                 :            : 
    1145                 :          0 : bool XclExpMultiCellBase::TryMergeXFIds( const XclExpMultiCellBase& rCell )
    1146                 :            : {
    1147         [ #  # ]:          0 :     if( GetLastXclCol() + 1 == rCell.GetXclCol() )
    1148                 :            :     {
    1149         [ #  # ]:          0 :         maXFIds.insert( maXFIds.end(), rCell.maXFIds.begin(), rCell.maXFIds.end() );
    1150                 :          0 :         return true;
    1151                 :            :     }
    1152                 :          0 :     return false;
    1153                 :            : }
    1154                 :            : 
    1155                 :          0 : void XclExpMultiCellBase::GetXFIndexes( ScfUInt16Vec& rXFIndexes ) const
    1156                 :            : {
    1157                 :            :     OSL_ENSURE( GetLastXclCol() < rXFIndexes.size(), "XclExpMultiCellBase::GetXFIndexes - vector too small" );
    1158         [ #  # ]:          0 :     ScfUInt16Vec::iterator aDestIt = rXFIndexes.begin() + GetXclCol();
    1159 [ #  # ][ #  # ]:          0 :     for( XclExpMultiXFIdDeq::const_iterator aIt = maXFIds.begin(), aEnd = maXFIds.end(); aIt != aEnd; ++aIt )
                 [ #  # ]
    1160                 :            :     {
    1161 [ #  # ][ #  # ]:          0 :         ::std::fill( aDestIt, aDestIt + aIt->mnCount, aIt->mnXFIndex );
    1162         [ #  # ]:          0 :         aDestIt += aIt->mnCount;
    1163                 :            :     }
    1164                 :          0 : }
    1165                 :            : 
    1166                 :          0 : void XclExpMultiCellBase::RemoveUnusedXFIndexes( const ScfUInt16Vec& rXFIndexes )
    1167                 :            : {
    1168                 :            :     // save last column before calling maXFIds.clear()
    1169         [ #  # ]:          0 :     sal_uInt16 nLastXclCol = GetLastXclCol();
    1170                 :            :     OSL_ENSURE( nLastXclCol < rXFIndexes.size(), "XclExpMultiCellBase::RemoveUnusedXFIndexes - XF index vector too small" );
    1171                 :            : 
    1172                 :            :     // build new XF index vector, containing passed XF indexes
    1173                 :          0 :     maXFIds.clear();
    1174         [ #  # ]:          0 :     XclExpMultiXFId aXFId( 0 );
    1175 [ #  # ][ #  # ]:          0 :     for( ScfUInt16Vec::const_iterator aIt = rXFIndexes.begin() + GetXclCol(), aEnd = rXFIndexes.begin() + nLastXclCol + 1; aIt != aEnd; ++aIt )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1176                 :            :     {
    1177                 :            :         // AppendXFId() tests XclExpXFIndex::mnXFId, set it too
    1178         [ #  # ]:          0 :         aXFId.mnXFId = aXFId.mnXFIndex = *aIt;
    1179         [ #  # ]:          0 :         AppendXFId( aXFId );
    1180                 :            :     }
    1181                 :            : 
    1182                 :            :     // remove leading and trailing unused XF indexes
    1183 [ #  # ][ #  # ]:          0 :     if( !maXFIds.empty() && (maXFIds.front().mnXFIndex == EXC_XF_NOTFOUND) )
         [ #  # ][ #  # ]
    1184                 :            :     {
    1185         [ #  # ]:          0 :         SetXclCol( GetXclCol() + maXFIds.front().mnCount );
    1186         [ #  # ]:          0 :         maXFIds.pop_front();
    1187                 :            :     }
    1188 [ #  # ][ #  # ]:          0 :     if( !maXFIds.empty() && (maXFIds.back().mnXFIndex == EXC_XF_NOTFOUND) )
         [ #  # ][ #  # ]
    1189         [ #  # ]:          0 :         maXFIds.pop_back();
    1190                 :            : 
    1191                 :            :     // The Save() function will skip all XF indexes equal to EXC_XF_NOTFOUND.
    1192                 :          0 : }
    1193                 :            : 
    1194                 :            : // ----------------------------------------------------------------------------
    1195                 :            : 
    1196                 :          8 : IMPL_FIXEDMEMPOOL_NEWDEL( XclExpBlankCell )
    1197                 :            : 
    1198                 :          0 : XclExpBlankCell::XclExpBlankCell( const XclAddress& rXclPos, const XclExpMultiXFId& rXFId ) :
    1199                 :          0 :     XclExpMultiCellBase( EXC_ID3_BLANK, EXC_ID_MULBLANK, 0, rXclPos )
    1200                 :            : {
    1201                 :            :     OSL_ENSURE( rXFId.mnCount > 0, "XclExpBlankCell::XclExpBlankCell - invalid count" );
    1202         [ #  # ]:          0 :     AppendXFId( rXFId );
    1203                 :          0 : }
    1204                 :            : 
    1205                 :          0 : XclExpBlankCell::XclExpBlankCell(
    1206                 :            :         const XclExpRoot& rRoot, const XclAddress& rXclPos, sal_uInt16 nLastXclCol,
    1207                 :            :         const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId ) :
    1208                 :          0 :     XclExpMultiCellBase( EXC_ID3_BLANK, EXC_ID_MULBLANK, 0, rXclPos )
    1209                 :            : {
    1210                 :            :     OSL_ENSURE( rXclPos.mnCol <= nLastXclCol, "XclExpBlankCell::XclExpBlankCell - invalid column range" );
    1211                 :            :     // #i46627# use default script type instead of ApiScriptType::WEAK
    1212         [ #  # ]:          0 :     AppendXFId( rRoot, pPattern, rRoot.GetDefApiScript(), nForcedXFId, nLastXclCol - rXclPos.mnCol + 1 );
    1213                 :          0 : }
    1214                 :            : 
    1215                 :          0 : bool XclExpBlankCell::TryMerge( const XclExpCellBase& rCell )
    1216                 :            : {
    1217         [ #  # ]:          0 :     const XclExpBlankCell* pBlankCell = dynamic_cast< const XclExpBlankCell* >( &rCell );
    1218 [ #  # ][ #  # ]:          0 :     return pBlankCell && TryMergeXFIds( *pBlankCell );
    1219                 :            : }
    1220                 :            : 
    1221                 :          0 : void XclExpBlankCell::GetBlankXFIndexes( ScfUInt16Vec& rXFIndexes ) const
    1222                 :            : {
    1223                 :          0 :     GetXFIndexes( rXFIndexes );
    1224                 :          0 : }
    1225                 :            : 
    1226                 :          0 : void XclExpBlankCell::RemoveUnusedBlankCells( const ScfUInt16Vec& rXFIndexes )
    1227                 :            : {
    1228                 :          0 :     RemoveUnusedXFIndexes( rXFIndexes );
    1229                 :          0 : }
    1230                 :            : 
    1231                 :          0 : void XclExpBlankCell::WriteContents( XclExpStream& /*rStrm*/, sal_uInt16 /*nRelCol*/ )
    1232                 :            : {
    1233                 :          0 : }
    1234                 :            : 
    1235                 :          0 : void XclExpBlankCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 /* nRelCol */ )
    1236                 :            : {
    1237                 :          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
    1238                 :            :     rWorksheet->singleElement( XML_c,
    1239                 :            :             XML_r,      XclXmlUtils::ToOString( rAddress ).getStr(),
    1240                 :            :             XML_s,      lcl_GetStyleId( rStrm, nXFId ).getStr(),
    1241 [ #  # ][ #  # ]:          0 :             FSEND );
    1242                 :          0 : }
    1243                 :            : 
    1244                 :            : // ----------------------------------------------------------------------------
    1245                 :            : 
    1246                 :          8 : IMPL_FIXEDMEMPOOL_NEWDEL( XclExpRkCell )
    1247                 :            : 
    1248                 :          0 : XclExpRkCell::XclExpRkCell(
    1249                 :            :         const XclExpRoot& rRoot, const XclAddress& rXclPos,
    1250                 :            :         const ScPatternAttr* pPattern, sal_uInt32 nForcedXFId, sal_Int32 nRkValue ) :
    1251         [ #  # ]:          0 :     XclExpMultiCellBase( EXC_ID_RK, EXC_ID_MULRK, 4, rXclPos )
    1252                 :            : {
    1253                 :            :     // #i41210# always use latin script for number cells - may look wrong for special number formats...
    1254         [ #  # ]:          0 :     AppendXFId( rRoot, pPattern, ApiScriptType::LATIN, nForcedXFId );
    1255         [ #  # ]:          0 :     maRkValues.push_back( nRkValue );
    1256                 :          0 : }
    1257                 :            : 
    1258                 :          0 : bool XclExpRkCell::TryMerge( const XclExpCellBase& rCell )
    1259                 :            : {
    1260         [ #  # ]:          0 :     const XclExpRkCell* pRkCell = dynamic_cast< const XclExpRkCell* >( &rCell );
    1261 [ #  # ][ #  # ]:          0 :     if( pRkCell && TryMergeXFIds( *pRkCell ) )
                 [ #  # ]
    1262                 :            :     {
    1263                 :          0 :         maRkValues.insert( maRkValues.end(), pRkCell->maRkValues.begin(), pRkCell->maRkValues.end() );
    1264                 :          0 :         return true;
    1265                 :            :     }
    1266                 :          0 :     return false;
    1267                 :            : }
    1268                 :            : 
    1269                 :          0 : void XclExpRkCell::WriteXmlContents( XclExpXmlStream& rStrm, const XclAddress& rAddress, sal_uInt32 nXFId, sal_uInt16 nRelCol )
    1270                 :            : {
    1271                 :          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
    1272                 :            :     rWorksheet->startElement( XML_c,
    1273                 :            :             XML_r,      XclXmlUtils::ToOString( rAddress ).getStr(),
    1274                 :            :             XML_s,      lcl_GetStyleId( rStrm, nXFId ).getStr(),
    1275                 :            :             XML_t,      "n",
    1276                 :            :             // OOXTODO: XML_cm, XML_vm, XML_ph
    1277 [ #  # ][ #  # ]:          0 :             FSEND );
    1278                 :          0 :     rWorksheet->startElement( XML_v, FSEND );
    1279                 :          0 :     rWorksheet->write( XclTools::GetDoubleFromRK( maRkValues[ nRelCol ] ) );
    1280                 :          0 :     rWorksheet->endElement( XML_v );
    1281                 :          0 :     rWorksheet->endElement( XML_c );
    1282                 :          0 : }
    1283                 :            : 
    1284                 :          0 : void XclExpRkCell::WriteContents( XclExpStream& rStrm, sal_uInt16 nRelCol )
    1285                 :            : {
    1286                 :            :     OSL_ENSURE( nRelCol < maRkValues.size(), "XclExpRkCell::WriteContents - overflow error" );
    1287                 :          0 :     rStrm << maRkValues[ nRelCol ];
    1288                 :          0 : }
    1289                 :            : 
    1290                 :            : // ============================================================================
    1291                 :            : // Rows and Columns
    1292                 :            : // ============================================================================
    1293                 :            : 
    1294                 :          0 : XclExpOutlineBuffer::XclExpOutlineBuffer( const XclExpRoot& rRoot, bool bRows ) :
    1295                 :            :         mpScOLArray( 0 ),
    1296                 :            :         maLevelInfos( SC_OL_MAXDEPTH ),
    1297                 :            :         mnCurrLevel( 0 ),
    1298                 :          0 :         mbCurrCollapse( false )
    1299                 :            : {
    1300 [ #  # ][ #  # ]:          0 :     if( const ScOutlineTable* pOutlineTable = rRoot.GetDoc().GetOutlineTable( rRoot.GetCurrScTab() ) )
    1301         [ #  # ]:          0 :         mpScOLArray = bRows ? pOutlineTable->GetRowArray() : pOutlineTable->GetColArray();
    1302                 :            : 
    1303         [ #  # ]:          0 :     if( mpScOLArray )
    1304         [ #  # ]:          0 :         for( size_t nLevel = 0; nLevel < SC_OL_MAXDEPTH; ++nLevel )
    1305 [ #  # ][ #  # ]:          0 :             if( const ScOutlineEntry* pEntry = mpScOLArray->GetEntryByPos( nLevel, 0 ) )
    1306         [ #  # ]:          0 :                 maLevelInfos[ nLevel ].mnScEndPos = pEntry->GetEnd();
    1307                 :          0 : }
    1308                 :            : 
    1309                 :          0 : void XclExpOutlineBuffer::UpdateColRow( SCCOLROW nScPos )
    1310                 :            : {
    1311         [ #  # ]:          0 :     if( mpScOLArray )
    1312                 :            :     {
    1313                 :            :         // find open level index for passed position
    1314                 :          0 :         size_t nNewOpenScLevel = 0; // new open level (0-based Calc index)
    1315                 :          0 :         sal_uInt8 nNewLevel = 0;    // new open level (1-based Excel index)
    1316                 :            : 
    1317 [ #  # ][ #  # ]:          0 :         if( mpScOLArray->FindTouchedLevel( nScPos, nScPos, nNewOpenScLevel ) )
    1318                 :          0 :             nNewLevel = static_cast< sal_uInt8 >( nNewOpenScLevel + 1 );
    1319                 :            :         // else nNewLevel keeps 0 to show that there are no groups
    1320                 :            : 
    1321                 :          0 :         mbCurrCollapse = false;
    1322         [ #  # ]:          0 :         if( nNewLevel >= mnCurrLevel )
    1323                 :            :         {
    1324                 :            :             // new level(s) opened, or no level closed - update all level infos
    1325         [ #  # ]:          0 :             for( sal_uInt16 nScLevel = 0; nScLevel <= nNewOpenScLevel; ++nScLevel )
    1326                 :            :             {
    1327                 :            :                 /*  In each level: check if a new group is started (there may be
    1328                 :            :                     neighbored groups without gap - therefore check ALL levels). */
    1329         [ #  # ]:          0 :                 if( maLevelInfos[ nScLevel ].mnScEndPos < nScPos )
    1330                 :            :                 {
    1331 [ #  # ][ #  # ]:          0 :                     if( const ScOutlineEntry* pEntry = mpScOLArray->GetEntryByPos( nScLevel, nScPos ) )
    1332                 :            :                     {
    1333         [ #  # ]:          0 :                         maLevelInfos[ nScLevel ].mnScEndPos = pEntry->GetEnd();
    1334         [ #  # ]:          0 :                         maLevelInfos[ nScLevel ].mbHidden = pEntry->IsHidden();
    1335                 :            :                     }
    1336                 :            :                 }
    1337                 :            :             }
    1338                 :            :         }
    1339                 :            :         else
    1340                 :            :         {
    1341                 :            :             // level(s) closed - check if any of the closed levels are collapsed
    1342                 :            :             // Calc uses 0-based level indexes
    1343                 :          0 :             sal_uInt16 nOldOpenScLevel = mnCurrLevel - 1;
    1344 [ #  # ][ #  # ]:          0 :             for( sal_uInt16 nScLevel = nNewOpenScLevel + 1; !mbCurrCollapse && (nScLevel <= nOldOpenScLevel); ++nScLevel )
                 [ #  # ]
    1345                 :          0 :                 mbCurrCollapse = maLevelInfos[ nScLevel ].mbHidden;
    1346                 :            :         }
    1347                 :            : 
    1348                 :            :         // cache new opened level
    1349                 :          0 :         mnCurrLevel = nNewLevel;
    1350                 :            :     }
    1351                 :          0 : }
    1352                 :            : 
    1353                 :            : // ----------------------------------------------------------------------------
    1354                 :            : 
    1355                 :          0 : XclExpGuts::XclExpGuts( const XclExpRoot& rRoot ) :
    1356                 :            :     XclExpRecord( EXC_ID_GUTS, 8 ),
    1357                 :            :     mnColLevels( 0 ),
    1358                 :            :     mnColWidth( 0 ),
    1359                 :            :     mnRowLevels( 0 ),
    1360                 :          0 :     mnRowWidth( 0 )
    1361                 :            : {
    1362 [ #  # ][ #  # ]:          0 :     if( const ScOutlineTable* pOutlineTable = rRoot.GetDoc().GetOutlineTable( rRoot.GetCurrScTab() ) )
    1363                 :            :     {
    1364                 :            :         // column outline groups
    1365         [ #  # ]:          0 :         if( const ScOutlineArray* pColArray = pOutlineTable->GetColArray() )
    1366 [ #  # ][ #  # ]:          0 :             mnColLevels = ulimit_cast< sal_uInt16 >( pColArray->GetDepth(), EXC_OUTLINE_MAX );
    1367         [ #  # ]:          0 :         if( mnColLevels )
    1368                 :            :         {
    1369                 :          0 :             ++mnColLevels;
    1370                 :          0 :             mnColWidth = 12 * mnColLevels + 5;
    1371                 :            :         }
    1372                 :            : 
    1373                 :            :         // row outline groups
    1374         [ #  # ]:          0 :         if( const ScOutlineArray* pRowArray = pOutlineTable->GetRowArray() )
    1375 [ #  # ][ #  # ]:          0 :             mnRowLevels = ulimit_cast< sal_uInt16 >( pRowArray->GetDepth(), EXC_OUTLINE_MAX );
    1376         [ #  # ]:          0 :         if( mnRowLevels )
    1377                 :            :         {
    1378                 :          0 :             ++mnRowLevels;
    1379                 :          0 :             mnRowWidth = 12 * mnRowLevels + 5;
    1380                 :            :         }
    1381                 :            :     }
    1382                 :          0 : }
    1383                 :            : 
    1384                 :          0 : void XclExpGuts::WriteBody( XclExpStream& rStrm )
    1385                 :            : {
    1386                 :          0 :     rStrm << mnRowWidth << mnColWidth << mnRowLevels << mnColLevels;
    1387                 :          0 : }
    1388                 :            : 
    1389                 :            : // ----------------------------------------------------------------------------
    1390                 :            : 
    1391                 :          0 : XclExpDimensions::XclExpDimensions( const XclExpRoot& rRoot ) :
    1392                 :            :     mnFirstUsedXclRow( 0 ),
    1393                 :            :     mnFirstFreeXclRow( 0 ),
    1394                 :            :     mnFirstUsedXclCol( 0 ),
    1395                 :          0 :     mnFirstFreeXclCol( 0 )
    1396                 :            : {
    1397   [ #  #  #  # ]:          0 :     switch( rRoot.GetBiff() )
    1398                 :            :     {
    1399         [ #  # ]:          0 :         case EXC_BIFF2: SetRecHeader( EXC_ID2_DIMENSIONS, 8 );  break;
    1400                 :            :         case EXC_BIFF3:
    1401                 :            :         case EXC_BIFF4:
    1402         [ #  # ]:          0 :         case EXC_BIFF5: SetRecHeader( EXC_ID3_DIMENSIONS, 10 ); break;
    1403         [ #  # ]:          0 :         case EXC_BIFF8: SetRecHeader( EXC_ID3_DIMENSIONS, 14 ); break;
    1404                 :            :         default:        DBG_ERROR_BIFF();
    1405                 :            :     }
    1406                 :          0 : }
    1407                 :            : 
    1408                 :          0 : void XclExpDimensions::SetDimensions(
    1409                 :            :         sal_uInt16 nFirstUsedXclCol, sal_uInt32 nFirstUsedXclRow,
    1410                 :            :         sal_uInt16 nFirstFreeXclCol, sal_uInt32 nFirstFreeXclRow )
    1411                 :            : {
    1412                 :          0 :     mnFirstUsedXclRow = nFirstUsedXclRow;
    1413                 :          0 :     mnFirstFreeXclRow = nFirstFreeXclRow;
    1414                 :          0 :     mnFirstUsedXclCol = nFirstUsedXclCol;
    1415                 :          0 :     mnFirstFreeXclCol = nFirstFreeXclCol;
    1416                 :          0 : }
    1417                 :            : 
    1418                 :          0 : void XclExpDimensions::SaveXml( XclExpXmlStream& rStrm )
    1419                 :            : {
    1420                 :          0 :     ScRange aRange;
    1421                 :          0 :     aRange.aStart.SetRow( (SCROW) mnFirstUsedXclRow );
    1422                 :          0 :     aRange.aStart.SetCol( (SCCOL) mnFirstUsedXclCol );
    1423                 :            : 
    1424 [ #  # ][ #  # ]:          0 :     if( mnFirstFreeXclRow != mnFirstUsedXclRow && mnFirstFreeXclCol != mnFirstUsedXclCol )
    1425                 :            :     {
    1426                 :          0 :         aRange.aEnd.SetRow( (SCROW) (mnFirstFreeXclRow-1) );
    1427                 :          0 :         aRange.aEnd.SetCol( (SCCOL) (mnFirstFreeXclCol-1) );
    1428                 :            :     }
    1429                 :            : 
    1430         [ #  # ]:          0 :     rStrm.GetCurrentStream()->singleElement( XML_dimension,
    1431                 :            :             XML_ref, XclXmlUtils::ToOString( aRange ).getStr(),
    1432 [ #  # ][ #  # ]:          0 :             FSEND );
    1433                 :          0 : }
    1434                 :            : 
    1435                 :          0 : void XclExpDimensions::WriteBody( XclExpStream& rStrm )
    1436                 :            : {
    1437                 :          0 :     XclBiff eBiff = rStrm.GetRoot().GetBiff();
    1438         [ #  # ]:          0 :     if( eBiff == EXC_BIFF8 )
    1439                 :          0 :         rStrm << mnFirstUsedXclRow << mnFirstFreeXclRow;
    1440                 :            :     else
    1441                 :          0 :         rStrm << static_cast< sal_uInt16 >( mnFirstUsedXclRow ) << static_cast< sal_uInt16 >( mnFirstFreeXclRow );
    1442                 :          0 :     rStrm << mnFirstUsedXclCol << mnFirstFreeXclCol;
    1443         [ #  # ]:          0 :     if( eBiff >= EXC_BIFF3 )
    1444                 :          0 :         rStrm << sal_uInt16( 0 );
    1445                 :          0 : }
    1446                 :            : 
    1447                 :            : // ============================================================================
    1448                 :            : 
    1449                 :            : namespace {
    1450                 :            : 
    1451                 :          0 : double lclGetCorrectedColWidth( const XclExpRoot& rRoot, sal_uInt16 nXclColWidth )
    1452                 :            : {
    1453                 :          0 :     long nFontHt = rRoot.GetFontBuffer().GetAppFontData().mnHeight;
    1454                 :          0 :     return nXclColWidth - XclTools::GetXclDefColWidthCorrection( nFontHt );
    1455                 :            : }
    1456                 :            : 
    1457                 :            : } // namespace
    1458                 :            : 
    1459                 :            : // ----------------------------------------------------------------------------
    1460                 :            : 
    1461                 :          0 : XclExpDefcolwidth::XclExpDefcolwidth( const XclExpRoot& rRoot ) :
    1462                 :            :     XclExpUInt16Record( EXC_ID_DEFCOLWIDTH, EXC_DEFCOLWIDTH_DEF ),
    1463         [ #  # ]:          0 :     XclExpRoot( rRoot )
    1464                 :            : {
    1465                 :          0 : }
    1466                 :            : 
    1467                 :          0 : bool XclExpDefcolwidth::IsDefWidth( sal_uInt16 nXclColWidth ) const
    1468                 :            : {
    1469                 :          0 :     double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth );
    1470                 :            :     // exactly matched, if difference is less than 1/16 of a character to the left or to the right
    1471                 :          0 :     return Abs( static_cast< long >( GetValue() * 256.0 - fNewColWidth + 0.5 ) ) < 16;
    1472                 :            : }
    1473                 :            : 
    1474                 :          0 : void XclExpDefcolwidth::SetDefWidth( sal_uInt16 nXclColWidth )
    1475                 :            : {
    1476                 :          0 :     double fNewColWidth = lclGetCorrectedColWidth( GetRoot(), nXclColWidth );
    1477                 :          0 :     SetValue( limit_cast< sal_uInt16 >( fNewColWidth / 256.0 + 0.5 ) );
    1478                 :          0 : }
    1479                 :            : 
    1480                 :            : // ----------------------------------------------------------------------------
    1481                 :            : 
    1482                 :          0 : XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot,
    1483                 :            :         SCCOL nScCol, SCROW nLastScRow, XclExpColOutlineBuffer& rOutlineBfr ) :
    1484                 :            :     XclExpRecord( EXC_ID_COLINFO, 12 ),
    1485                 :            :     XclExpRoot( rRoot ),
    1486                 :            :     mnWidth( 0 ),
    1487                 :            :     mnFlags( 0 ),
    1488                 :            :     mnFirstXclCol( static_cast< sal_uInt16 >( nScCol ) ),
    1489 [ #  # ][ #  # ]:          0 :     mnLastXclCol( static_cast< sal_uInt16 >( nScCol ) )
    1490                 :            : {
    1491                 :          0 :     ScDocument& rDoc = GetDoc();
    1492                 :          0 :     SCTAB nScTab = GetCurrScTab();
    1493                 :            : 
    1494                 :            :     // column default format
    1495         [ #  # ]:          0 :     maXFId.mnXFId = GetXFBuffer().Insert(
    1496 [ #  # ][ #  # ]:          0 :         rDoc.GetMostUsedPattern( nScCol, 0, nLastScRow, nScTab ), GetDefApiScript() );
    1497                 :            : 
    1498                 :            :     // column width
    1499         [ #  # ]:          0 :     sal_uInt16 nScWidth = rDoc.GetColWidth( nScCol, nScTab );
    1500         [ #  # ]:          0 :     mnWidth = XclTools::GetXclColumnWidth( nScWidth, GetCharWidth() );
    1501                 :            : 
    1502                 :            :     // column flags
    1503         [ #  # ]:          0 :     ::set_flag( mnFlags, EXC_COLINFO_HIDDEN, rDoc.ColHidden(nScCol, nScTab) );
    1504                 :            : 
    1505                 :            :     // outline data
    1506         [ #  # ]:          0 :     rOutlineBfr.Update( nScCol );
    1507                 :          0 :     ::set_flag( mnFlags, EXC_COLINFO_COLLAPSED, rOutlineBfr.IsCollapsed() );
    1508         [ #  # ]:          0 :     ::insert_value( mnFlags, rOutlineBfr.GetLevel(), 8, 3 );
    1509                 :          0 : }
    1510                 :            : 
    1511                 :          0 : sal_uInt16 XclExpColinfo::ConvertXFIndexes()
    1512                 :            : {
    1513                 :          0 :     maXFId.ConvertXFIndex( GetRoot() );
    1514                 :          0 :     return maXFId.mnXFIndex;
    1515                 :            : }
    1516                 :            : 
    1517                 :          0 : bool XclExpColinfo::IsDefault( const XclExpDefcolwidth& rDefColWidth ) const
    1518                 :            : {
    1519 [ #  # ][ #  # ]:          0 :     return (maXFId.mnXFIndex == EXC_XF_DEFAULTCELL) && (mnFlags == 0) && rDefColWidth.IsDefWidth( mnWidth );
                 [ #  # ]
    1520                 :            : }
    1521                 :            : 
    1522                 :          0 : bool XclExpColinfo::TryMerge( const XclExpColinfo& rColInfo )
    1523                 :            : {
    1524 [ #  # ][ #  # ]:          0 :     if( (maXFId.mnXFIndex == rColInfo.maXFId.mnXFIndex) &&
         [ #  # ][ #  # ]
    1525                 :            :         (mnWidth == rColInfo.mnWidth) &&
    1526                 :            :         (mnFlags == rColInfo.mnFlags) &&
    1527                 :            :         (mnLastXclCol + 1 == rColInfo.mnFirstXclCol) )
    1528                 :            :     {
    1529                 :          0 :         mnLastXclCol = rColInfo.mnLastXclCol;
    1530                 :          0 :         return true;
    1531                 :            :     }
    1532                 :          0 :     return false;
    1533                 :            : }
    1534                 :            : 
    1535                 :          0 : void XclExpColinfo::WriteBody( XclExpStream& rStrm )
    1536                 :            : {
    1537                 :            :     // if last column is equal to last possible column, Excel adds one more
    1538                 :          0 :     sal_uInt16 nLastXclCol = mnLastXclCol;
    1539         [ #  # ]:          0 :     if( nLastXclCol == static_cast< sal_uInt16 >( rStrm.GetRoot().GetMaxPos().Col() ) )
    1540                 :          0 :         ++nLastXclCol;
    1541                 :            : 
    1542                 :          0 :     rStrm   << mnFirstXclCol
    1543                 :          0 :             << nLastXclCol
    1544                 :          0 :             << mnWidth
    1545                 :          0 :             << maXFId.mnXFIndex
    1546                 :          0 :             << mnFlags
    1547                 :          0 :             << sal_uInt16( 0 );
    1548                 :          0 : }
    1549                 :            : 
    1550                 :          0 : void XclExpColinfo::SaveXml( XclExpXmlStream& rStrm )
    1551                 :            : {
    1552                 :            :     // if last column is equal to last possible column, Excel adds one more
    1553                 :          0 :     sal_uInt16 nLastXclCol = mnLastXclCol;
    1554         [ #  # ]:          0 :     if( nLastXclCol == static_cast< sal_uInt16 >( rStrm.GetRoot().GetMaxPos().Col() ) )
    1555                 :          0 :         ++nLastXclCol;
    1556                 :            : 
    1557         [ #  # ]:          0 :     rStrm.GetCurrentStream()->singleElement( XML_col,
    1558                 :            :             // OOXTODO: XML_bestFit,
    1559                 :          0 :             XML_collapsed,      XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_COLLAPSED ) ),
    1560                 :            :             // OOXTODO: XML_customWidth,
    1561                 :          0 :             XML_hidden,         XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_COLINFO_HIDDEN ) ),
    1562                 :            :             XML_max,            OString::valueOf( (sal_Int32) (nLastXclCol+1) ).getStr(),
    1563                 :            :             XML_min,            OString::valueOf( (sal_Int32) (mnFirstXclCol+1) ).getStr(),
    1564                 :            :             // OOXTODO: XML_outlineLevel,
    1565                 :            :             // OOXTODO: XML_phonetic,
    1566                 :            :             XML_style,          lcl_GetStyleId( rStrm, maXFId.mnXFIndex ).getStr(),
    1567                 :            :             XML_width,          OString::valueOf( (double) (mnWidth / 255.0) ).getStr(),
    1568         [ #  # ]:          0 :             FSEND );
           [ #  #  #  # ]
                 [ #  # ]
    1569                 :          0 : }
    1570                 :            : 
    1571                 :            : // ----------------------------------------------------------------------------
    1572                 :            : 
    1573                 :          0 : XclExpColinfoBuffer::XclExpColinfoBuffer( const XclExpRoot& rRoot ) :
    1574                 :            :     XclExpRoot( rRoot ),
    1575                 :            :     maDefcolwidth( rRoot ),
    1576 [ #  # ][ #  # ]:          0 :     maOutlineBfr( rRoot )
         [ #  # ][ #  # ]
    1577                 :            : {
    1578                 :          0 : }
    1579                 :            : 
    1580                 :          0 : void XclExpColinfoBuffer::Initialize( SCROW nLastScRow )
    1581                 :            : {
    1582                 :            : 
    1583         [ #  # ]:          0 :     for( sal_uInt16 nScCol = 0, nLastScCol = GetMaxPos().Col(); nScCol <= nLastScCol; ++nScCol )
    1584         [ #  # ]:          0 :         maColInfos.AppendNewRecord( new XclExpColinfo( GetRoot(), nScCol, nLastScRow, maOutlineBfr ) );
    1585                 :          0 : }
    1586                 :            : 
    1587                 :          0 : void XclExpColinfoBuffer::Finalize( ScfUInt16Vec& rXFIndexes )
    1588                 :            : {
    1589                 :          0 :     rXFIndexes.clear();
    1590         [ #  # ]:          0 :     rXFIndexes.reserve( maColInfos.GetSize() );
    1591                 :            : 
    1592                 :            :     size_t nPos, nSize;
    1593                 :            : 
    1594                 :            :     // do not cache the record list size, it may change in the loop
    1595         [ #  # ]:          0 :     for( nPos = 0; nPos < maColInfos.GetSize(); ++nPos )
    1596                 :            :     {
    1597         [ #  # ]:          0 :         XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
    1598         [ #  # ]:          0 :         xRec->ConvertXFIndexes();
    1599                 :            : 
    1600                 :            :         // try to merge with previous record
    1601         [ #  # ]:          0 :         if( nPos > 0 )
    1602                 :            :         {
    1603         [ #  # ]:          0 :             XclExpColinfoRef xPrevRec = maColInfos.GetRecord( nPos - 1 );
    1604         [ #  # ]:          0 :             if( xPrevRec->TryMerge( *xRec ) )
    1605                 :            :                 // adjust nPos to get the next COLINFO record at the same position
    1606 [ #  # ][ #  # ]:          0 :                 maColInfos.RemoveRecord( nPos-- );
    1607                 :            :         }
    1608         [ #  # ]:          0 :     }
    1609                 :            : 
    1610                 :            :     // put XF indexes into passed vector, collect use count of all different widths
    1611                 :            :     typedef ::std::map< sal_uInt16, sal_uInt16 > XclExpWidthMap;
    1612         [ #  # ]:          0 :     XclExpWidthMap aWidthMap;
    1613                 :          0 :     sal_uInt16 nMaxColCount = 0;
    1614                 :          0 :     sal_uInt16 nMaxUsedWidth = 0;
    1615         [ #  # ]:          0 :     for( nPos = 0, nSize = maColInfos.GetSize(); nPos < nSize; ++nPos )
    1616                 :            :     {
    1617         [ #  # ]:          0 :         XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
    1618                 :          0 :         sal_uInt16 nColCount = xRec->GetColCount();
    1619                 :            : 
    1620                 :            :         // add XF index to passed vector
    1621         [ #  # ]:          0 :         rXFIndexes.resize( rXFIndexes.size() + nColCount, xRec->GetXFIndex() );
    1622                 :            : 
    1623                 :            :         // collect use count of column width
    1624                 :          0 :         sal_uInt16 nWidth = xRec->GetColWidth();
    1625         [ #  # ]:          0 :         sal_uInt16& rnMapCount = aWidthMap[ nWidth ];
    1626                 :          0 :         rnMapCount = rnMapCount + nColCount;
    1627         [ #  # ]:          0 :         if( rnMapCount > nMaxColCount )
    1628                 :            :         {
    1629                 :          0 :             nMaxColCount = rnMapCount;
    1630                 :          0 :             nMaxUsedWidth = nWidth;
    1631                 :            :         }
    1632         [ #  # ]:          0 :     }
    1633         [ #  # ]:          0 :     maDefcolwidth.SetDefWidth( nMaxUsedWidth );
    1634                 :            : 
    1635                 :            :     // remove all default COLINFO records
    1636                 :          0 :     nPos = 0;
    1637         [ #  # ]:          0 :     while( nPos < maColInfos.GetSize() )
    1638                 :            :     {
    1639         [ #  # ]:          0 :         XclExpColinfoRef xRec = maColInfos.GetRecord( nPos );
    1640 [ #  # ][ #  # ]:          0 :         if( xRec->IsDefault( maDefcolwidth ) )
    1641         [ #  # ]:          0 :             maColInfos.RemoveRecord( nPos );
    1642                 :            :         else
    1643                 :          0 :             ++nPos;
    1644         [ #  # ]:          0 :     }
    1645                 :          0 : }
    1646                 :            : 
    1647                 :          0 : void XclExpColinfoBuffer::Save( XclExpStream& rStrm )
    1648                 :            : {
    1649                 :            :     // DEFCOLWIDTH
    1650                 :          0 :     maDefcolwidth.Save( rStrm );
    1651                 :            :     // COLINFO records
    1652                 :          0 :     maColInfos.Save( rStrm );
    1653                 :          0 : }
    1654                 :            : 
    1655                 :          0 : void XclExpColinfoBuffer::SaveXml( XclExpXmlStream& rStrm )
    1656                 :            : {
    1657         [ #  # ]:          0 :     if( maColInfos.IsEmpty() )
    1658                 :          0 :         return;
    1659                 :            : 
    1660                 :          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
    1661                 :            :     rWorksheet->startElement( XML_cols,
    1662                 :          0 :             FSEND );
    1663                 :          0 :     maColInfos.SaveXml( rStrm );
    1664                 :          0 :     rWorksheet->endElement( XML_cols );
    1665                 :            : }
    1666                 :            : 
    1667                 :            : // ============================================================================
    1668                 :            : 
    1669                 :          0 : XclExpDefaultRowData::XclExpDefaultRowData() :
    1670                 :            :     mnFlags( EXC_DEFROW_DEFAULTFLAGS ),
    1671                 :          0 :     mnHeight( EXC_DEFROW_DEFAULTHEIGHT )
    1672                 :            : {
    1673                 :          0 : }
    1674                 :            : 
    1675                 :          0 : XclExpDefaultRowData::XclExpDefaultRowData( const XclExpRow& rRow ) :
    1676                 :            :     mnFlags( EXC_DEFROW_DEFAULTFLAGS ),
    1677                 :          0 :     mnHeight( rRow.GetHeight() )
    1678                 :            : {
    1679                 :          0 :     ::set_flag( mnFlags, EXC_DEFROW_HIDDEN, rRow.IsHidden() );
    1680                 :          0 :     ::set_flag( mnFlags, EXC_DEFROW_UNSYNCED, rRow.IsUnsynced() );
    1681                 :          0 : }
    1682                 :            : 
    1683                 :          0 : bool operator<( const XclExpDefaultRowData& rLeft, const XclExpDefaultRowData& rRight )
    1684                 :            : {
    1685                 :            :     return (rLeft.mnHeight < rRight.mnHeight) ||
    1686 [ #  # ][ #  # ]:          0 :         ((rLeft.mnHeight == rRight.mnHeight) && (rLeft.mnFlags < rRight.mnFlags));
                 [ #  # ]
    1687                 :            : }
    1688                 :            : 
    1689                 :            : // ----------------------------------------------------------------------------
    1690                 :            : 
    1691                 :          0 : XclExpDefrowheight::XclExpDefrowheight() :
    1692                 :          0 :     XclExpRecord( EXC_ID3_DEFROWHEIGHT, 4 )
    1693                 :            : {
    1694                 :          0 : }
    1695                 :            : 
    1696                 :          0 : void XclExpDefrowheight::SetDefaultData( const XclExpDefaultRowData& rDefData )
    1697                 :            : {
    1698                 :          0 :     maDefData = rDefData;
    1699                 :          0 : }
    1700                 :            : 
    1701                 :          0 : void XclExpDefrowheight::WriteBody( XclExpStream& rStrm )
    1702                 :            : {
    1703                 :            :     OSL_ENSURE_BIFF( rStrm.GetRoot().GetBiff() >= EXC_BIFF3 );
    1704                 :          0 :     rStrm << maDefData.mnFlags << maDefData.mnHeight;
    1705                 :          0 : }
    1706                 :            : 
    1707                 :            : // ----------------------------------------------------------------------------
    1708                 :            : 
    1709                 :          0 : XclExpRow::XclExpRow( const XclExpRoot& rRoot, sal_uInt32 nXclRow,
    1710                 :            :         XclExpRowOutlineBuffer& rOutlineBfr, bool bAlwaysEmpty ) :
    1711                 :            :     XclExpRecord( EXC_ID3_ROW, 16 ),
    1712                 :            :     XclExpRoot( rRoot ),
    1713                 :            :     mnXclRow( nXclRow ),
    1714                 :            :     mnHeight( 0 ),
    1715                 :            :     mnFlags( EXC_ROW_DEFAULTFLAGS ),
    1716                 :            :     mnXFIndex( EXC_XF_DEFAULTCELL ),
    1717                 :            :     mnOutlineLevel( 0 ),
    1718                 :            :     mbAlwaysEmpty( bAlwaysEmpty ),
    1719 [ #  # ][ #  # ]:          0 :     mbEnabled( true )
    1720                 :            : {
    1721                 :          0 :     SCTAB nScTab = GetCurrScTab();
    1722                 :          0 :     SCROW nScRow = static_cast< SCROW >( mnXclRow );
    1723                 :            : 
    1724                 :            :     // *** Row flags *** ------------------------------------------------------
    1725                 :            : 
    1726         [ #  # ]:          0 :     sal_uInt8 nRowFlags = GetDoc().GetRowFlags( nScRow, nScTab );
    1727                 :          0 :     bool bUserHeight = ::get_flag< sal_uInt8 >( nRowFlags, CR_MANUALSIZE );
    1728         [ #  # ]:          0 :     bool bHidden = GetDoc().RowHidden(nScRow, nScTab);
    1729                 :          0 :     ::set_flag( mnFlags, EXC_ROW_UNSYNCED, bUserHeight );
    1730                 :          0 :     ::set_flag( mnFlags, EXC_ROW_HIDDEN, bHidden );
    1731                 :            : 
    1732                 :            :     // *** Row height *** -----------------------------------------------------
    1733                 :            : 
    1734                 :            :     // Always get the actual row height even if the manual size flag is not set,
    1735                 :            :     // to correctly export the heights of rows with wrapped texts.
    1736                 :            : 
    1737         [ #  # ]:          0 :     mnHeight = GetDoc().GetRowHeight(nScRow, nScTab, false);
    1738                 :            : 
    1739                 :            :     // *** Outline data *** ---------------------------------------------------
    1740                 :            : 
    1741         [ #  # ]:          0 :     rOutlineBfr.Update( nScRow );
    1742                 :          0 :     ::set_flag( mnFlags, EXC_ROW_COLLAPSED, rOutlineBfr.IsCollapsed() );
    1743         [ #  # ]:          0 :     ::insert_value( mnFlags, rOutlineBfr.GetLevel(), 0, 3 );
    1744         [ #  # ]:          0 :     mnOutlineLevel = rOutlineBfr.GetLevel();
    1745                 :            : 
    1746                 :            :     // *** Progress bar *** ---------------------------------------------------
    1747                 :            : 
    1748         [ #  # ]:          0 :     XclExpProgressBar& rProgress = GetProgressBar();
    1749         [ #  # ]:          0 :     rProgress.IncRowRecordCount();
    1750         [ #  # ]:          0 :     rProgress.Progress();
    1751                 :          0 : }
    1752                 :            : 
    1753                 :          0 : void XclExpRow::AppendCell( XclExpCellRef xCell, bool bIsMergedBase )
    1754                 :            : {
    1755                 :            :     OSL_ENSURE( !mbAlwaysEmpty, "XclExpRow::AppendCell - row is marked to be always empty" );
    1756                 :            :     // try to merge with last existing cell
    1757         [ #  # ]:          0 :     InsertCell( xCell, maCellList.GetSize(), bIsMergedBase );
    1758                 :          0 : }
    1759                 :            : 
    1760                 :          0 : void XclExpRow::Finalize( const ScfUInt16Vec& rColXFIndexes )
    1761                 :            : {
    1762                 :            :     size_t nPos, nSize;
    1763                 :            : 
    1764                 :            :     // *** Convert XF identifiers *** -----------------------------------------
    1765                 :            : 
    1766                 :            :     // additionally collect the blank XF indexes
    1767                 :          0 :     size_t nColCount = GetMaxPos().Col() + 1;
    1768                 :            :     OSL_ENSURE( rColXFIndexes.size() == nColCount, "XclExpRow::Finalize - wrong column XF index count" );
    1769                 :            : 
    1770         [ #  # ]:          0 :     ScfUInt16Vec aXFIndexes( nColCount, EXC_XF_NOTFOUND );
    1771         [ #  # ]:          0 :     for( nPos = 0, nSize = maCellList.GetSize(); nPos < nSize; ++nPos )
    1772                 :            :     {
    1773         [ #  # ]:          0 :         XclExpCellRef xCell = maCellList.GetRecord( nPos );
    1774         [ #  # ]:          0 :         xCell->ConvertXFIndexes( GetRoot() );
    1775         [ #  # ]:          0 :         xCell->GetBlankXFIndexes( aXFIndexes );
    1776         [ #  # ]:          0 :     }
    1777                 :            : 
    1778                 :            :     // *** Fill gaps with BLANK/MULBLANK cell records *** ---------------------
    1779                 :            : 
    1780                 :            :     /*  This is needed because nonexistant cells in Calc are not formatted at all,
    1781                 :            :         but in Excel they would have the column default format. Blank cells that
    1782                 :            :         are equal to the respective column default are removed later in this function. */
    1783         [ #  # ]:          0 :     if( !mbAlwaysEmpty )
    1784                 :            :     {
    1785                 :            :         // XF identifier representing default cell XF
    1786 [ #  # ][ #  # ]:          0 :         XclExpMultiXFId aXFId( XclExpXFBuffer::GetDefCellXFId() );
    1787         [ #  # ]:          0 :         aXFId.ConvertXFIndex( GetRoot() );
    1788                 :            : 
    1789                 :          0 :         nPos = 0;
    1790         [ #  # ]:          0 :         while( nPos <= maCellList.GetSize() )  // don't cache list size, may change in the loop
    1791                 :            :         {
    1792                 :            :             // get column index that follows previous cell
    1793 [ #  # ][ #  # ]:          0 :             sal_uInt16 nFirstFreeXclCol = (nPos > 0) ? (maCellList.GetRecord( nPos - 1 )->GetLastXclCol() + 1) : 0;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1794                 :            :             // get own column index
    1795 [ #  # ][ #  # ]:          0 :             sal_uInt16 nNextUsedXclCol = (nPos < maCellList.GetSize()) ? maCellList.GetRecord( nPos )->GetXclCol() : (GetMaxPos().Col() + 1);
         [ #  # ][ #  # ]
                 [ #  # ]
    1796                 :            : 
    1797                 :            :             // is there a gap?
    1798         [ #  # ]:          0 :             if( nFirstFreeXclCol < nNextUsedXclCol )
    1799                 :            :             {
    1800                 :          0 :                 aXFId.mnCount = nNextUsedXclCol - nFirstFreeXclCol;
    1801 [ #  # ][ #  # ]:          0 :                 XclExpCellRef xNewCell( new XclExpBlankCell( XclAddress( nFirstFreeXclCol, mnXclRow ), aXFId ) );
                 [ #  # ]
    1802                 :            :                 // insert the cell, InsertCell() may merge it with existing BLANK records
    1803 [ #  # ][ #  # ]:          0 :                 InsertCell( xNewCell, nPos, false );
                 [ #  # ]
    1804                 :            :                 // insert default XF indexes into aXFIndexes
    1805                 :            :                 ::std::fill( aXFIndexes.begin() + nFirstFreeXclCol,
    1806 [ #  # ][ #  # ]:          0 :                     aXFIndexes.begin() + nNextUsedXclCol, aXFId.mnXFIndex );
         [ #  # ][ #  # ]
    1807                 :            :                 // don't step forward with nPos, InsertCell() may remove records
    1808                 :            :             }
    1809                 :            :             else
    1810                 :          0 :                 ++nPos;
    1811                 :            :         }
    1812                 :            :     }
    1813                 :            : 
    1814                 :            :     // *** Find default row format *** ----------------------------------------
    1815                 :            : 
    1816                 :          0 :     ScfUInt16Vec::iterator aCellBeg = aXFIndexes.begin(), aCellEnd = aXFIndexes.end(), aCellIt;
    1817                 :          0 :     ScfUInt16Vec::const_iterator aColBeg = rColXFIndexes.begin(), aColIt;
    1818                 :            : 
    1819                 :            :     // find most used XF index in the row
    1820                 :            :     typedef ::std::map< sal_uInt16, size_t > XclExpXFIndexMap;
    1821         [ #  # ]:          0 :     XclExpXFIndexMap aIndexMap;
    1822                 :          0 :     sal_uInt16 nRowXFIndex = EXC_XF_DEFAULTCELL;
    1823                 :          0 :     size_t nMaxXFCount = 0;
    1824 [ #  # ][ #  # ]:          0 :     for( aCellIt = aCellBeg; aCellIt != aCellEnd; ++aCellIt )
                 [ #  # ]
    1825                 :            :     {
    1826 [ #  # ][ #  # ]:          0 :         if( *aCellIt != EXC_XF_NOTFOUND )
    1827                 :            :         {
    1828 [ #  # ][ #  # ]:          0 :             size_t& rnCount = aIndexMap[ *aCellIt ];
    1829                 :          0 :             ++rnCount;
    1830         [ #  # ]:          0 :             if( rnCount > nMaxXFCount )
    1831                 :            :             {
    1832         [ #  # ]:          0 :                 nRowXFIndex = *aCellIt;
    1833                 :          0 :                 nMaxXFCount = rnCount;
    1834                 :            :             }
    1835                 :            :         }
    1836                 :            :     }
    1837                 :            : 
    1838                 :            :     // decide whether to use the row default XF index or column default XF indexes
    1839                 :          0 :     bool bUseColDefXFs = nRowXFIndex == EXC_XF_DEFAULTCELL;
    1840         [ #  # ]:          0 :     if( !bUseColDefXFs )
    1841                 :            :     {
    1842                 :            :         // count needed XF indexes for blank cells with and without row default XF index
    1843                 :          0 :         size_t nXFCountWithRowDefXF = 0;
    1844                 :          0 :         size_t nXFCountWithoutRowDefXF = 0;
    1845 [ #  # ][ #  # ]:          0 :         for( aCellIt = aCellBeg, aColIt = aColBeg; aCellIt != aCellEnd; ++aCellIt, ++aColIt )
         [ #  # ][ #  # ]
    1846                 :            :         {
    1847         [ #  # ]:          0 :             sal_uInt16 nXFIndex = *aCellIt;
    1848         [ #  # ]:          0 :             if( nXFIndex != EXC_XF_NOTFOUND )
    1849                 :            :             {
    1850         [ #  # ]:          0 :                 if( nXFIndex != nRowXFIndex )
    1851                 :          0 :                     ++nXFCountWithRowDefXF;     // with row default XF index
    1852 [ #  # ][ #  # ]:          0 :                 if( nXFIndex != *aColIt )
    1853                 :          0 :                     ++nXFCountWithoutRowDefXF;  // without row default XF index
    1854                 :            :             }
    1855                 :            :         }
    1856                 :            : 
    1857                 :            :         // use column XF indexes if this would cause less or equal number of BLANK records
    1858                 :          0 :         bUseColDefXFs = nXFCountWithoutRowDefXF <= nXFCountWithRowDefXF;
    1859                 :            :     }
    1860                 :            : 
    1861                 :            :     // *** Remove unused BLANK cell records *** -------------------------------
    1862                 :            : 
    1863         [ #  # ]:          0 :     if( bUseColDefXFs )
    1864                 :            :     {
    1865                 :            :         // use column default XF indexes
    1866                 :            :         // #i194#: remove cell XF indexes equal to column default XF indexes
    1867 [ #  # ][ #  # ]:          0 :         for( aCellIt = aCellBeg, aColIt = aColBeg; aCellIt != aCellEnd; ++aCellIt, ++aColIt )
         [ #  # ][ #  # ]
    1868 [ #  # ][ #  # ]:          0 :             if( *aCellIt == *aColIt )
                 [ #  # ]
    1869         [ #  # ]:          0 :                 *aCellIt = EXC_XF_NOTFOUND;
    1870                 :            :     }
    1871                 :            :     else
    1872                 :            :     {
    1873                 :            :         // use row default XF index
    1874                 :          0 :         mnXFIndex = nRowXFIndex;
    1875                 :          0 :         ::set_flag( mnFlags, EXC_ROW_USEDEFXF );
    1876                 :            :         // #98133#, #i194#, #i27407#: remove cell XF indexes equal to row default XF index
    1877 [ #  # ][ #  # ]:          0 :         for( aCellIt = aCellBeg; aCellIt != aCellEnd; ++aCellIt )
                 [ #  # ]
    1878 [ #  # ][ #  # ]:          0 :             if( *aCellIt == nRowXFIndex )
    1879         [ #  # ]:          0 :                 *aCellIt = EXC_XF_NOTFOUND;
    1880                 :            :     }
    1881                 :            : 
    1882                 :            :     // remove unused parts of BLANK/MULBLANK cell records
    1883                 :          0 :     nPos = 0;
    1884         [ #  # ]:          0 :     while( nPos < maCellList.GetSize() )   // do not cache list size, may change in the loop
    1885                 :            :     {
    1886         [ #  # ]:          0 :         XclExpCellRef xCell = maCellList.GetRecord( nPos );
    1887         [ #  # ]:          0 :         xCell->RemoveUnusedBlankCells( aXFIndexes );
    1888 [ #  # ][ #  # ]:          0 :         if( xCell->IsEmpty() )
    1889         [ #  # ]:          0 :             maCellList.RemoveRecord( nPos );
    1890                 :            :         else
    1891                 :          0 :             ++nPos;
    1892         [ #  # ]:          0 :     }
    1893                 :            : 
    1894                 :            :     // progress bar includes disabled rows
    1895 [ #  # ][ #  # ]:          0 :     GetProgressBar().Progress();
    1896                 :          0 : }
    1897                 :            : 
    1898                 :          0 : sal_uInt16 XclExpRow::GetFirstUsedXclCol() const
    1899                 :            : {
    1900 [ #  # ][ #  # ]:          0 :     return maCellList.IsEmpty() ? 0 : maCellList.GetFirstRecord()->GetXclCol();
         [ #  # ][ #  # ]
    1901                 :            : }
    1902                 :            : 
    1903                 :          0 : sal_uInt16 XclExpRow::GetFirstFreeXclCol() const
    1904                 :            : {
    1905 [ #  # ][ #  # ]:          0 :     return maCellList.IsEmpty() ? 0 : (maCellList.GetLastRecord()->GetLastXclCol() + 1);
         [ #  # ][ #  # ]
                 [ #  # ]
    1906                 :            : }
    1907                 :            : 
    1908                 :          0 : bool XclExpRow::IsDefaultable() const
    1909                 :            : {
    1910                 :          0 :     const sal_uInt16 nAllowedFlags = EXC_ROW_DEFAULTFLAGS | EXC_ROW_HIDDEN | EXC_ROW_UNSYNCED;
    1911 [ #  # ][ #  # ]:          0 :     return !::get_flag( mnFlags, static_cast< sal_uInt16 >( ~nAllowedFlags ) ) && IsEmpty();
    1912                 :            : }
    1913                 :            : 
    1914                 :          0 : void XclExpRow::DisableIfDefault( const XclExpDefaultRowData& rDefRowData )
    1915                 :            : {
    1916                 :          0 :     mbEnabled = !IsDefaultable() ||
    1917                 :            :         (mnHeight != rDefRowData.mnHeight) ||
    1918                 :          0 :         (IsHidden() != rDefRowData.IsHidden()) ||
    1919   [ #  #  #  # ]:          0 :         (IsUnsynced() != rDefRowData.IsUnsynced());
         [ #  # ][ #  # ]
    1920                 :          0 : }
    1921                 :            : 
    1922                 :          0 : void XclExpRow::WriteCellList( XclExpStream& rStrm )
    1923                 :            : {
    1924                 :            :     OSL_ENSURE( mbEnabled || maCellList.IsEmpty(), "XclExpRow::WriteCellList - cells in disabled row" );
    1925                 :          0 :     maCellList.Save( rStrm );
    1926                 :          0 : }
    1927                 :            : 
    1928                 :          0 : void XclExpRow::Save( XclExpStream& rStrm )
    1929                 :            : {
    1930         [ #  # ]:          0 :     if( mbEnabled )
    1931                 :          0 :         XclExpRecord::Save( rStrm );
    1932                 :          0 : }
    1933                 :            : 
    1934                 :          0 : void XclExpRow::InsertCell( XclExpCellRef xCell, size_t nPos, bool bIsMergedBase )
    1935                 :            : {
    1936                 :            :     OSL_ENSURE( xCell, "XclExpRow::InsertCell - missing cell" );
    1937                 :            : 
    1938                 :            :     /*  If we have a multi-line text in a merged cell, and the resulting
    1939                 :            :         row height has not been confirmed, we need to force the EXC_ROW_UNSYNCED
    1940                 :            :         flag to be true to ensure Excel works correctly. */
    1941 [ #  # ][ #  # ]:          0 :     if( bIsMergedBase && xCell->IsMultiLineText() )
         [ #  # ][ #  # ]
    1942                 :          0 :         ::set_flag( mnFlags, EXC_ROW_UNSYNCED );
    1943                 :            : 
    1944                 :            :     // try to merge with previous cell, insert the new cell if not successful
    1945         [ #  # ]:          0 :     XclExpCellRef xPrevCell = maCellList.GetRecord( nPos - 1 );
    1946 [ #  # ][ #  # ]:          0 :     if( xPrevCell && xPrevCell->TryMerge( *xCell ) )
         [ #  # ][ #  # ]
    1947         [ #  # ]:          0 :         xCell = xPrevCell;
    1948                 :            :     else
    1949 [ #  # ][ #  # ]:          0 :         maCellList.InsertRecord( xCell, nPos++ );
                 [ #  # ]
    1950                 :            :     // nPos points now to following cell
    1951                 :            : 
    1952                 :            :     // try to merge with following cell, remove it if successful
    1953         [ #  # ]:          0 :     XclExpCellRef xNextCell = maCellList.GetRecord( nPos );
    1954 [ #  # ][ #  # ]:          0 :     if( xNextCell && xCell->TryMerge( *xNextCell ) )
         [ #  # ][ #  # ]
    1955 [ #  # ][ #  # ]:          0 :         maCellList.RemoveRecord( nPos );
                 [ #  # ]
    1956                 :          0 : }
    1957                 :            : 
    1958                 :          0 : void XclExpRow::WriteBody( XclExpStream& rStrm )
    1959                 :            : {
    1960                 :          0 :     rStrm   << static_cast< sal_uInt16 >(mnXclRow)
    1961                 :          0 :             << GetFirstUsedXclCol()
    1962                 :          0 :             << GetFirstFreeXclCol()
    1963                 :          0 :             << mnHeight
    1964                 :          0 :             << sal_uInt32( 0 )
    1965                 :          0 :             << mnFlags
    1966                 :          0 :             << mnXFIndex;
    1967                 :          0 : }
    1968                 :            : 
    1969                 :          0 : void XclExpRow::SaveXml( XclExpXmlStream& rStrm )
    1970                 :            : {
    1971         [ #  # ]:          0 :     if( !mbEnabled )
    1972                 :          0 :         return;
    1973                 :          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
    1974                 :          0 :     bool haveFormat = ::get_flag( mnFlags, EXC_ROW_USEDEFXF );
    1975                 :            :     rWorksheet->startElement( XML_row,
    1976                 :            :             XML_r,              OString::valueOf( (sal_Int32) (mnXclRow+1) ).getStr(),
    1977                 :            :             // OOXTODO: XML_spans,          optional
    1978   [ #  #  #  # ]:          0 :             XML_s,              haveFormat ? lcl_GetStyleId( rStrm, mnXFIndex ).getStr() : NULL,
                 [ #  # ]
    1979                 :            :             XML_customFormat,   XclXmlUtils::ToPsz( haveFormat ),
    1980                 :            :             XML_ht,             OString::valueOf( (double) mnHeight / 20.0 ).getStr(),
    1981                 :          0 :             XML_hidden,         XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_HIDDEN ) ),
    1982                 :          0 :             XML_customHeight,   XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_UNSYNCED ) ),
    1983                 :            :             XML_outlineLevel,   OString::valueOf( (sal_Int32) mnOutlineLevel ).getStr(),
    1984                 :          0 :             XML_collapsed,      XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_COLLAPSED ) ),
    1985                 :            :             // OOXTODO: XML_thickTop,       bool
    1986                 :            :             // OOXTODO: XML_thickBot,       bool
    1987                 :            :             // OOXTODO: XML_ph,             bool
    1988 [ #  # ][ #  # ]:          0 :             FSEND );
                 [ #  # ]
           [ #  #  #  # ]
    1989                 :            :     // OOXTODO: XML_extLst
    1990                 :          0 :     maCellList.SaveXml( rStrm );
    1991                 :          0 :     rWorksheet->endElement( XML_row );
    1992                 :            : }
    1993                 :            : 
    1994                 :            : // ----------------------------------------------------------------------------
    1995                 :            : 
    1996                 :          0 : XclExpRowBuffer::XclExpRowBuffer( const XclExpRoot& rRoot ) :
    1997                 :            :     XclExpRoot( rRoot ),
    1998                 :            :     maOutlineBfr( rRoot ),
    1999 [ #  # ][ #  # ]:          0 :     maDimensions( rRoot )
         [ #  # ][ #  # ]
    2000                 :            : {
    2001                 :          0 : }
    2002                 :            : 
    2003                 :          0 : void XclExpRowBuffer::AppendCell( XclExpCellRef xCell, bool bIsMergedBase )
    2004                 :            : {
    2005                 :            :     OSL_ENSURE( xCell, "XclExpRowBuffer::AppendCell - missing cell" );
    2006 [ #  # ][ #  # ]:          0 :     GetOrCreateRow( xCell->GetXclRow(), false ).AppendCell( xCell, bIsMergedBase );
    2007                 :          0 : }
    2008                 :            : 
    2009                 :          0 : void XclExpRowBuffer::CreateRows( SCROW nFirstFreeScRow )
    2010                 :            : {
    2011         [ #  # ]:          0 :     if( nFirstFreeScRow > 0 )
    2012                 :          0 :         GetOrCreateRow( static_cast< sal_uInt16 >( nFirstFreeScRow - 1 ), true );
    2013                 :          0 : }
    2014                 :            : 
    2015                 :          0 : void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt16Vec& rColXFIndexes )
    2016                 :            : {
    2017                 :            :     // *** Finalize all rows *** ----------------------------------------------
    2018                 :            : 
    2019 [ #  # ][ #  # ]:          0 :     GetProgressBar().ActivateFinalRowsSegment();
    2020                 :            : 
    2021                 :          0 :     RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end();
    2022         [ #  # ]:          0 :     for (itr = itrBeg; itr != itrEnd; ++itr)
    2023         [ #  # ]:          0 :         itr->second->Finalize(rColXFIndexes);
    2024                 :            : 
    2025                 :            :     // *** Default row format *** ---------------------------------------------
    2026                 :            : 
    2027                 :            :     typedef ::std::map< XclExpDefaultRowData, size_t > XclExpDefRowDataMap;
    2028         [ #  # ]:          0 :     XclExpDefRowDataMap aDefRowMap;
    2029                 :            : 
    2030                 :          0 :     XclExpDefaultRowData aMaxDefData;
    2031                 :          0 :     size_t nMaxDefCount = 0;
    2032                 :            :     // only look for default format in existing rows, if there are more than unused
    2033         [ #  # ]:          0 :     for (itr = itrBeg; itr != itrEnd; ++itr)
    2034                 :            :     {
    2035                 :          0 :         const RowRef& rRow = itr->second;
    2036 [ #  # ][ #  # ]:          0 :         if (rRow->IsDefaultable())
    2037                 :            :         {
    2038         [ #  # ]:          0 :             XclExpDefaultRowData aDefData( *rRow );
    2039         [ #  # ]:          0 :             size_t& rnDefCount = aDefRowMap[ aDefData ];
    2040                 :          0 :             ++rnDefCount;
    2041         [ #  # ]:          0 :             if( rnDefCount > nMaxDefCount )
    2042                 :            :             {
    2043                 :          0 :                 nMaxDefCount = rnDefCount;
    2044                 :          0 :                 aMaxDefData = aDefData;
    2045                 :            :             }
    2046                 :            :         }
    2047                 :            :     }
    2048                 :            : 
    2049                 :            :     // return the default row format to caller
    2050                 :          0 :     rDefRowData = aMaxDefData;
    2051                 :            : 
    2052                 :            :     // *** Disable unused ROW records, find used area *** ---------------------
    2053                 :            : 
    2054                 :          0 :     sal_uInt16 nFirstUsedXclCol = SAL_MAX_UINT16;
    2055                 :          0 :     sal_uInt16 nFirstFreeXclCol = 0;
    2056                 :          0 :     sal_uInt32 nFirstUsedXclRow = SAL_MAX_UINT32;
    2057                 :          0 :     sal_uInt32 nFirstFreeXclRow = 0;
    2058                 :            : 
    2059         [ #  # ]:          0 :     for (itr = itrBeg; itr != itrEnd; ++itr)
    2060                 :            :     {
    2061                 :          0 :         const RowRef& rRow = itr->second;
    2062                 :            :         // disable unused rows
    2063         [ #  # ]:          0 :         rRow->DisableIfDefault( aMaxDefData );
    2064                 :            : 
    2065                 :            :         // find used column range
    2066 [ #  # ][ #  # ]:          0 :         if( !rRow->IsEmpty() )      // empty rows return (0...0) as used range
    2067                 :            :         {
    2068 [ #  # ][ #  # ]:          0 :             nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, rRow->GetFirstUsedXclCol() );
    2069 [ #  # ][ #  # ]:          0 :             nFirstFreeXclCol = ::std::max( nFirstFreeXclCol, rRow->GetFirstFreeXclCol() );
    2070                 :            :         }
    2071                 :            : 
    2072                 :            :         // find used row range
    2073         [ #  # ]:          0 :         if( rRow->IsEnabled() )
    2074                 :            :         {
    2075                 :          0 :             sal_uInt16 nXclRow = rRow->GetXclRow();
    2076         [ #  # ]:          0 :             nFirstUsedXclRow = ::std::min< sal_uInt32 >( nFirstUsedXclRow, nXclRow );
    2077         [ #  # ]:          0 :             nFirstFreeXclRow = ::std::max< sal_uInt32 >( nFirstFreeXclRow, nXclRow + 1 );
    2078                 :            :         }
    2079                 :            :     }
    2080                 :            : 
    2081                 :            :     // adjust start position, if there are no or only empty/disabled ROW records
    2082         [ #  # ]:          0 :     nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, nFirstFreeXclCol );
    2083         [ #  # ]:          0 :     nFirstUsedXclRow = ::std::min( nFirstUsedXclRow, nFirstFreeXclRow );
    2084                 :            : 
    2085                 :            :     // initialize the DIMENSIONS record
    2086                 :            :     maDimensions.SetDimensions(
    2087                 :          0 :         nFirstUsedXclCol, nFirstUsedXclRow, nFirstFreeXclCol, nFirstFreeXclRow );
    2088                 :          0 : }
    2089                 :            : 
    2090                 :          0 : void XclExpRowBuffer::Save( XclExpStream& rStrm )
    2091                 :            : {
    2092                 :            :     // DIMENSIONS record
    2093         [ #  # ]:          0 :     maDimensions.Save( rStrm );
    2094                 :            : 
    2095                 :            :     // save in blocks of 32 rows, each block contains first all ROWs, then all cells
    2096                 :          0 :     size_t nSize = maRowMap.size();
    2097                 :          0 :     RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end();
    2098                 :          0 :     RowMap::iterator itrBlkStart = maRowMap.begin(), itrBlkEnd = maRowMap.begin();
    2099         [ #  # ]:          0 :     sal_uInt16 nStartXclRow = (nSize == 0) ? 0 : itrBeg->second->GetXclRow();
    2100                 :            : 
    2101                 :            : 
    2102         [ #  # ]:          0 :     for (itr = itrBeg; itr != itrEnd; ++itr)
    2103                 :            :     {
    2104                 :            :         // find end of row block
    2105 [ #  # ][ #  # ]:          0 :         while( (itrBlkEnd != itrEnd) && (itrBlkEnd->second->GetXclRow() - nStartXclRow < EXC_ROW_ROWBLOCKSIZE) )
                 [ #  # ]
    2106                 :          0 :             ++itrBlkEnd;
    2107                 :            : 
    2108                 :            :         // write the ROW records
    2109                 :          0 :         RowMap::iterator itRow;
    2110         [ #  # ]:          0 :         for( itRow = itrBlkStart; itRow != itrBlkEnd; ++itRow )
    2111         [ #  # ]:          0 :             itRow->second->Save( rStrm );
    2112                 :            : 
    2113                 :            :         // write the cell records
    2114         [ #  # ]:          0 :         for( itRow = itrBlkStart; itRow != itrBlkEnd; ++itRow )
    2115         [ #  # ]:          0 :              itRow->second->WriteCellList( rStrm );
    2116                 :            : 
    2117         [ #  # ]:          0 :         itrBlkStart = (itrBlkEnd == itrEnd) ? itrBlkEnd : itrBlkEnd++;
    2118                 :          0 :         nStartXclRow += EXC_ROW_ROWBLOCKSIZE;
    2119                 :            :     }
    2120                 :          0 : }
    2121                 :            : 
    2122                 :          0 : void XclExpRowBuffer::SaveXml( XclExpXmlStream& rStrm )
    2123                 :            : {
    2124                 :          0 :     sal_Int32 nNonEmpty = 0;
    2125                 :          0 :     RowMap::iterator itr = maRowMap.begin(), itrEnd = maRowMap.end();
    2126         [ #  # ]:          0 :     for (; itr != itrEnd; ++itr)
    2127         [ #  # ]:          0 :         if (itr->second->IsEnabled())
    2128                 :          0 :             ++nNonEmpty;
    2129                 :            : 
    2130         [ #  # ]:          0 :     if (nNonEmpty == 0)
    2131                 :            :     {
    2132 [ #  # ][ #  # ]:          0 :         rStrm.GetCurrentStream()->singleElement( XML_sheetData, FSEND );
    2133                 :          0 :         return;
    2134                 :            :     }
    2135                 :            : 
    2136         [ #  # ]:          0 :     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
    2137         [ #  # ]:          0 :     rWorksheet->startElement( XML_sheetData, FSEND );
    2138         [ #  # ]:          0 :     for (itr = maRowMap.begin(); itr != itrEnd; ++itr)
    2139         [ #  # ]:          0 :         itr->second->SaveXml(rStrm);
    2140         [ #  # ]:          0 :     rWorksheet->endElement( XML_sheetData );
    2141                 :            : }
    2142                 :            : 
    2143                 :          0 : XclExpDimensions* XclExpRowBuffer::GetDimensions()
    2144                 :            : {
    2145                 :          0 :     return &maDimensions;
    2146                 :            : }
    2147                 :            : 
    2148                 :          0 : XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysEmpty )
    2149                 :            : {
    2150                 :          0 :     RowMap::iterator itr = maRowMap.begin();
    2151                 :          0 :     ScDocument& rDoc = GetRoot().GetDoc();
    2152                 :          0 :     SCTAB nScTab = GetRoot().GetCurrScTab();
    2153         [ #  # ]:          0 :     for ( size_t nFrom = maRowMap.size(); nFrom <= nXclRow; ++nFrom )
    2154                 :            :     {
    2155         [ #  # ]:          0 :         itr = maRowMap.find(nFrom);
    2156         [ #  # ]:          0 :         if ( itr == maRowMap.end() )
    2157                 :            :         {
    2158                 :            :             // only create RowMap entries for rows that differ from previous,
    2159                 :            :             // or if it is the desired row
    2160 [ #  # ][ #  # ]:          0 :             if ( !nFrom || ( nFrom == nXclRow ) || ( nFrom && ( rDoc.GetRowHeight(nFrom, nScTab, false) != rDoc.GetRowHeight(nFrom-1, nScTab, false) ) ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2161                 :            :             {
    2162 [ #  # ][ #  # ]:          0 :                 RowRef p(new XclExpRow(GetRoot(), nFrom, maOutlineBfr, bRowAlwaysEmpty));
                 [ #  # ]
    2163 [ #  # ][ #  # ]:          0 :                 maRowMap.insert(RowMap::value_type(nFrom, p));
         [ #  # ][ #  # ]
    2164                 :            :             }
    2165                 :            :         }
    2166                 :            :     }
    2167         [ #  # ]:          0 :     itr = maRowMap.find(nXclRow);
    2168                 :          0 :     return *itr->second;
    2169                 :            : 
    2170                 :            : }
    2171                 :            : 
    2172                 :            : // ============================================================================
    2173                 :            : // Cell Table
    2174                 :            : // ============================================================================
    2175                 :            : 
    2176                 :          0 : XclExpCellTable::XclExpCellTable( const XclExpRoot& rRoot ) :
    2177                 :            :     XclExpRoot( rRoot ),
    2178                 :            :     maColInfoBfr( rRoot ),
    2179                 :            :     maRowBfr( rRoot ),
    2180                 :            :     maArrayBfr( rRoot ),
    2181                 :            :     maShrfmlaBfr( rRoot ),
    2182                 :            :     maTableopBfr( rRoot ),
    2183         [ #  # ]:          0 :     mxDefrowheight( new XclExpDefrowheight ),
    2184         [ #  # ]:          0 :     mxGuts( new XclExpGuts( rRoot ) ),
    2185         [ #  # ]:          0 :     mxNoteList( new XclExpNoteList ),
    2186         [ #  # ]:          0 :     mxMergedcells( new XclExpMergedcells( rRoot ) ),
    2187         [ #  # ]:          0 :     mxHyperlinkList( new XclExpHyperlinkList ),
    2188         [ #  # ]:          0 :     mxDval( new XclExpDval( rRoot ) ),
    2189 [ #  # ][ #  # ]:          0 :     mxExtLst( new XclExtLst( rRoot ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2190                 :            : {
    2191                 :          0 :     ScDocument& rDoc = GetDoc();
    2192                 :          0 :     SCTAB nScTab = GetCurrScTab();
    2193         [ #  # ]:          0 :     SvNumberFormatter& rFormatter = GetFormatter();
    2194                 :            : 
    2195                 :            :     // maximum sheet limits
    2196                 :          0 :     SCCOL nMaxScCol = GetMaxPos().Col();
    2197                 :          0 :     SCROW nMaxScRow = GetMaxPos().Row();
    2198                 :            : 
    2199                 :            :     // find used area (non-empty cells)
    2200                 :            :     SCCOL nLastUsedScCol;
    2201                 :            :     SCROW nLastUsedScRow;
    2202         [ #  # ]:          0 :     rDoc.GetTableArea( nScTab, nLastUsedScCol, nLastUsedScRow );
    2203                 :            : 
    2204         [ #  # ]:          0 :     if(nLastUsedScCol > nMaxScCol)
    2205                 :          0 :         nLastUsedScCol = nMaxScCol;
    2206                 :            : 
    2207         [ #  # ]:          0 :     if(nLastUsedScRow > nMaxScRow)
    2208                 :          0 :         nLastUsedScRow = nMaxScRow;
    2209                 :            : 
    2210                 :          0 :     ScRange aUsedRange( 0, 0, nScTab, nLastUsedScCol, nLastUsedScRow, nScTab );
    2211 [ #  # ][ #  # ]:          0 :     GetAddressConverter().ValidateRange( aUsedRange, true );
    2212                 :          0 :     nLastUsedScCol = aUsedRange.aEnd.Col();
    2213                 :          0 :     nLastUsedScRow = aUsedRange.aEnd.Row();
    2214                 :            : 
    2215                 :            :     // first row without any set attributes (height/hidden/...)
    2216         [ #  # ]:          0 :     SCROW nFirstUnflaggedScRow = rDoc.GetLastFlaggedRow( nScTab ) + 1;
    2217                 :            : 
    2218                 :            :     // find range of outlines
    2219                 :          0 :     SCROW nFirstUngroupedScRow = 0;
    2220 [ #  # ][ #  # ]:          0 :     if( const ScOutlineTable* pOutlineTable = rDoc.GetOutlineTable( nScTab ) )
    2221                 :            :     {
    2222                 :            :         SCCOLROW nScStartPos, nScEndPos;
    2223         [ #  # ]:          0 :         if( const ScOutlineArray* pRowArray = pOutlineTable->GetRowArray() )
    2224                 :            :         {
    2225         [ #  # ]:          0 :             pRowArray->GetRange( nScStartPos, nScEndPos );
    2226                 :            :             // +1 because open/close button is in next row in Excel, +1 for "end->first unused"
    2227                 :          0 :             nFirstUngroupedScRow = static_cast< SCROW >( nScEndPos + 2 );
    2228                 :            :         }
    2229                 :            :     }
    2230                 :            : 
    2231                 :            :     // column settings
    2232                 :            :     /*  #i30411# Files saved with SO7/OOo1.x with nonstandard default column
    2233                 :            :         formatting cause big Excel files, because all rows from row 1 to row
    2234                 :            :         32000 are exported. Now, if the used area goes exactly to row 32000,
    2235                 :            :         use this row as default and ignore all rows >32000.
    2236                 :            :         #i59220# Tolerance of +-128 rows for inserted/removed rows. */
    2237 [ #  # ][ #  # ]:          0 :     if( (31871 <= nLastUsedScRow) && (nLastUsedScRow <= 32127) && (nFirstUnflaggedScRow < nLastUsedScRow) && (nFirstUngroupedScRow <= nLastUsedScRow) )
         [ #  # ][ #  # ]
    2238                 :          0 :         nMaxScRow = nLastUsedScRow;
    2239         [ #  # ]:          0 :     maColInfoBfr.Initialize( nMaxScRow );
    2240                 :            : 
    2241                 :            :     // range for cell iterator
    2242                 :          0 :     SCCOL nLastIterScCol = nMaxScCol;
    2243         [ #  # ]:          0 :     SCROW nLastIterScRow = ulimit_cast< SCROW >( nLastUsedScRow, nMaxScRow );
    2244         [ #  # ]:          0 :     ScUsedAreaIterator aIt( &rDoc, nScTab, 0, 0, nLastIterScCol, nLastIterScRow );
    2245                 :            : 
    2246                 :            :     // activate the correct segment and sub segment at the progress bar
    2247 [ #  # ][ #  # ]:          0 :     GetProgressBar().ActivateCreateRowsSegment();
    2248                 :            : 
    2249 [ #  # ][ #  # ]:          0 :     for( bool bIt = aIt.GetNext(); bIt; bIt = aIt.GetNext() )
                 [ #  # ]
    2250                 :            :     {
    2251                 :          0 :         SCCOL nScCol = aIt.GetStartCol();
    2252                 :          0 :         SCROW nScRow = aIt.GetRow();
    2253                 :          0 :         SCCOL nLastScCol = aIt.GetEndCol();
    2254                 :          0 :         ScAddress aScPos( nScCol, nScRow, nScTab );
    2255                 :            : 
    2256                 :          0 :         XclAddress aXclPos( static_cast< sal_uInt16 >( nScCol ), static_cast< sal_uInt32 >( nScRow ) );
    2257                 :          0 :         sal_uInt16 nLastXclCol = static_cast< sal_uInt16 >( nLastScCol );
    2258                 :            : 
    2259                 :          0 :         const ScBaseCell* pScCell = aIt.GetCell();
    2260         [ #  # ]:          0 :         XclExpCellRef xCell;
    2261                 :            : 
    2262                 :          0 :         const ScPatternAttr* pPattern = aIt.GetPattern();
    2263                 :            : 
    2264                 :            :         // handle overlapped merged cells before creating the cell record
    2265                 :          0 :         sal_uInt32 nMergeBaseXFId = EXC_XFID_NOTFOUND;
    2266                 :          0 :         bool bIsMergedBase = false;
    2267         [ #  # ]:          0 :         if( pPattern )
    2268                 :            :         {
    2269                 :          0 :             const SfxItemSet& rItemSet = pPattern->GetItemSet();
    2270                 :            :             // base cell in a merged range
    2271         [ #  # ]:          0 :             const ScMergeAttr& rMergeItem = GETITEM( rItemSet, ScMergeAttr, ATTR_MERGE );
    2272                 :          0 :             bIsMergedBase = rMergeItem.IsMerged();
    2273                 :            :             /*  overlapped cell in a merged range; in Excel all merged cells
    2274                 :            :                 must contain same XF index, for correct border */
    2275         [ #  # ]:          0 :             const ScMergeFlagAttr& rMergeFlagItem = GETITEM( rItemSet, ScMergeFlagAttr, ATTR_MERGE_FLAG );
    2276         [ #  # ]:          0 :             if( rMergeFlagItem.IsOverlapped() )
    2277         [ #  # ]:          0 :                 nMergeBaseXFId = mxMergedcells->GetBaseXFId( aScPos );
    2278                 :            :         }
    2279                 :            : 
    2280         [ #  # ]:          0 :         String aAddNoteText;    // additional text to be appended to a note
    2281                 :            : 
    2282         [ #  # ]:          0 :         CellType eCellType = pScCell ? pScCell->GetCellType() : CELLTYPE_NONE;
    2283   [ #  #  #  #  :          0 :         switch( eCellType )
                      # ]
    2284                 :            :         {
    2285                 :            :             case CELLTYPE_VALUE:
    2286                 :            :             {
    2287                 :          0 :                 double fValue = static_cast< const ScValueCell* >( pScCell )->GetValue();
    2288                 :            : 
    2289                 :            :                 // try to create a Boolean cell
    2290 [ #  # ][ #  # ]:          0 :                 if( pPattern && ((fValue == 0.0) || (fValue == 1.0)) )
                 [ #  # ]
    2291                 :            :                 {
    2292         [ #  # ]:          0 :                     sal_uLong nScNumFmt = GETITEMVALUE( pPattern->GetItemSet(), SfxUInt32Item, ATTR_VALUE_FORMAT, sal_uLong );
    2293 [ #  # ][ #  # ]:          0 :                     if( rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL )
    2294                 :            :                         xCell.reset( new XclExpBooleanCell(
    2295 [ #  # ][ #  # ]:          0 :                             GetRoot(), aXclPos, pPattern, nMergeBaseXFId, fValue != 0.0 ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    2296                 :            :                 }
    2297                 :            : 
    2298                 :            :                 // try to create an RK value (compressed floating-point number)
    2299                 :            :                 sal_Int32 nRkValue;
    2300 [ #  # ][ #  # ]:          0 :                 if( !xCell && XclTools::GetRKFromDouble( nRkValue, fValue ) )
         [ #  # ][ #  # ]
    2301                 :            :                     xCell.reset( new XclExpRkCell(
    2302 [ #  # ][ #  # ]:          0 :                         GetRoot(), aXclPos, pPattern, nMergeBaseXFId, nRkValue ) );
                 [ #  # ]
    2303                 :            : 
    2304                 :            :                 // else: simple floating-point number cell
    2305         [ #  # ]:          0 :                 if( !xCell )
    2306                 :            :                     xCell.reset( new XclExpNumberCell(
    2307 [ #  # ][ #  # ]:          0 :                         GetRoot(), aXclPos, pPattern, nMergeBaseXFId, fValue ) );
                 [ #  # ]
    2308                 :            :             }
    2309                 :          0 :             break;
    2310                 :            : 
    2311                 :            :             case CELLTYPE_STRING:
    2312                 :            :             {
    2313                 :          0 :                 const ScStringCell& rScStrCell = *static_cast< const ScStringCell* >( pScCell );
    2314                 :            :                 xCell.reset( new XclExpLabelCell(
    2315 [ #  # ][ #  # ]:          0 :                     GetRoot(), aXclPos, pPattern, nMergeBaseXFId, rScStrCell ) );
                 [ #  # ]
    2316                 :            :             }
    2317                 :          0 :             break;
    2318                 :            : 
    2319                 :            :             case CELLTYPE_EDIT:
    2320                 :            :             {
    2321                 :          0 :                 const ScEditCell& rScEditCell = *static_cast< const ScEditCell* >( pScCell );
    2322         [ #  # ]:          0 :                 XclExpHyperlinkHelper aLinkHelper( GetRoot(), aScPos );
    2323                 :            :                 xCell.reset( new XclExpLabelCell(
    2324 [ #  # ][ #  # ]:          0 :                     GetRoot(), aXclPos, pPattern, nMergeBaseXFId, rScEditCell, aLinkHelper ) );
                 [ #  # ]
    2325                 :            : 
    2326                 :            :                 // add a single created HLINK record to the record list
    2327 [ #  # ][ #  # ]:          0 :                 if( aLinkHelper.HasLinkRecord() )
    2328 [ #  # ][ #  # ]:          0 :                     mxHyperlinkList->AppendRecord( aLinkHelper.GetLinkRecord() );
                 [ #  # ]
    2329                 :            :                 // add list of multiple URLs to the additional cell note text
    2330         [ #  # ]:          0 :                 if( aLinkHelper.HasMultipleUrls() )
    2331 [ #  # ][ #  # ]:          0 :                     ScGlobal::AddToken( aAddNoteText, aLinkHelper.GetUrlList(), '\n', 2 );
    2332                 :            :             }
    2333                 :          0 :             break;
    2334                 :            : 
    2335                 :            :             case CELLTYPE_FORMULA:
    2336                 :            :             {
    2337         [ #  # ]:          0 :                 const ScFormulaCell& rScFmlaCell = *static_cast< const ScFormulaCell* >( pScCell );
    2338                 :            :                 xCell.reset( new XclExpFormulaCell(
    2339                 :          0 :                     GetRoot(), aXclPos, pPattern, nMergeBaseXFId,
    2340 [ #  # ][ #  # ]:          0 :                     rScFmlaCell, maArrayBfr, maShrfmlaBfr, maTableopBfr ) );
                 [ #  # ]
    2341                 :            :             }
    2342                 :          0 :             break;
    2343                 :            : 
    2344                 :            :             default:
    2345                 :            :                 OSL_FAIL( "XclExpCellTable::XclExpCellTable - unknown cell type" );
    2346                 :            :                 // run-through!
    2347                 :            :             case CELLTYPE_NONE:
    2348                 :            :             case CELLTYPE_NOTE:
    2349                 :            :             {
    2350                 :            :                 xCell.reset( new XclExpBlankCell(
    2351 [ #  # ][ #  # ]:          0 :                     GetRoot(), aXclPos, nLastXclCol, pPattern, nMergeBaseXFId ) );
                 [ #  # ]
    2352                 :            :             }
    2353                 :          0 :             break;
    2354                 :            :         }
    2355                 :            : 
    2356                 :            :         // insert the cell into the current row
    2357         [ #  # ]:          0 :         if( xCell )
    2358 [ #  # ][ #  # ]:          0 :             maRowBfr.AppendCell( xCell, bIsMergedBase );
                 [ #  # ]
    2359                 :            : 
    2360         [ #  # ]:          0 :         if ( aAddNoteText.Len()  )
    2361 [ #  # ][ #  # ]:          0 :             mxNoteList->AppendNewRecord( new XclExpNote( GetRoot(), aScPos, NULL, aAddNoteText ) );
                 [ #  # ]
    2362                 :            : 
    2363                 :            :         // other sheet contents
    2364         [ #  # ]:          0 :         if( pPattern )
    2365                 :            :         {
    2366                 :          0 :             const SfxItemSet& rItemSet = pPattern->GetItemSet();
    2367                 :            : 
    2368                 :            :             // base cell in a merged range
    2369         [ #  # ]:          0 :             if( bIsMergedBase )
    2370                 :            :             {
    2371         [ #  # ]:          0 :                 const ScMergeAttr& rMergeItem = GETITEM( rItemSet, ScMergeAttr, ATTR_MERGE );
    2372                 :          0 :                 ScRange aScRange( aScPos );
    2373         [ #  # ]:          0 :                 aScRange.aEnd.IncCol( rMergeItem.GetColMerge() - 1 );
    2374         [ #  # ]:          0 :                 aScRange.aEnd.IncRow( rMergeItem.GetRowMerge() - 1 );
    2375 [ #  # ][ #  # ]:          0 :                 sal_uInt32 nXFId = xCell ? xCell->GetFirstXFId() : EXC_XFID_NOTFOUND;
    2376                 :            :                 // blank cells merged vertically may occur repeatedly
    2377                 :            :                 OSL_ENSURE( (aScRange.aStart.Col() == aScRange.aEnd.Col()) || (nScCol == nLastScCol),
    2378                 :            :                     "XclExpCellTable::XclExpCellTable - invalid repeated blank merged cell" );
    2379         [ #  # ]:          0 :                 for( SCCOL nIndex = nScCol; nIndex <= nLastScCol; ++nIndex )
    2380                 :            :                 {
    2381         [ #  # ]:          0 :                     mxMergedcells->AppendRange( aScRange, nXFId );
    2382         [ #  # ]:          0 :                     aScRange.aStart.IncCol();
    2383         [ #  # ]:          0 :                     aScRange.aEnd.IncCol();
    2384                 :            :                 }
    2385                 :            :             }
    2386                 :            : 
    2387                 :            :             // data validation
    2388 [ #  # ][ #  # ]:          0 :             if( ScfTools::CheckItem( rItemSet, ATTR_VALIDDATA, false ) )
    2389                 :            :             {
    2390         [ #  # ]:          0 :                 sal_uLong nScHandle = GETITEMVALUE( rItemSet, SfxUInt32Item, ATTR_VALIDDATA, sal_uLong );
    2391                 :          0 :                 ScRange aScRange( aScPos );
    2392                 :          0 :                 aScRange.aEnd.SetCol( nLastScCol );
    2393         [ #  # ]:          0 :                 mxDval->InsertCellRange( aScRange, nScHandle );
    2394                 :            :             }
    2395                 :            :         }
    2396 [ #  # ][ #  # ]:          0 :     }
    2397                 :            : 
    2398                 :            :     // create missing row settings for rows anyhow flagged or with outlines
    2399 [ #  # ][ #  # ]:          0 :     maRowBfr.CreateRows( ::std::max( nFirstUnflaggedScRow, nFirstUngroupedScRow ) );
                 [ #  # ]
    2400                 :          0 : }
    2401                 :            : 
    2402                 :          0 : void XclExpCellTable::Finalize()
    2403                 :            : {
    2404                 :            :     // Finalize multiple operations.
    2405         [ #  # ]:          0 :     maTableopBfr.Finalize();
    2406                 :            : 
    2407                 :            :     /*  Finalize column buffer. This calculates column default XF indexes from
    2408                 :            :         the XF identifiers and fills a vector with these XF indexes. */
    2409         [ #  # ]:          0 :     ScfUInt16Vec aColXFIndexes;
    2410         [ #  # ]:          0 :     maColInfoBfr.Finalize( aColXFIndexes );
    2411                 :            : 
    2412                 :            :     /*  Finalize row buffer. This calculates all cell XF indexes from the XF
    2413                 :            :         identifiers. Then the XF index vector aColXFIndexes (filled above) is
    2414                 :            :         used to calculate the row default formats. With this, all unneeded blank
    2415                 :            :         cell records (equal to row default or column default) will be removed.
    2416                 :            :         The function returns the (most used) default row format in aDefRowData. */
    2417                 :          0 :     XclExpDefaultRowData aDefRowData;
    2418         [ #  # ]:          0 :     maRowBfr.Finalize( aDefRowData, aColXFIndexes );
    2419                 :            : 
    2420                 :            :     // Initialize the DEFROWHEIGHT record.
    2421                 :          0 :     mxDefrowheight->SetDefaultData( aDefRowData );
    2422                 :          0 : }
    2423                 :            : 
    2424                 :          0 : XclExpRecordRef XclExpCellTable::CreateRecord( sal_uInt16 nRecId ) const
    2425                 :            : {
    2426                 :          0 :     XclExpRecordRef xRec;
    2427   [ #  #  #  #  :          0 :     switch( nRecId )
             #  #  #  #  
                      # ]
    2428                 :            :     {
    2429 [ #  # ][ #  # ]:          0 :         case EXC_ID3_DIMENSIONS:    xRec.reset( new XclExpDelegatingRecord( const_cast<XclExpRowBuffer*>(&maRowBfr)->GetDimensions() ) );   break;
                 [ #  # ]
    2430         [ #  # ]:          0 :         case EXC_ID2_DEFROWHEIGHT:  xRec = mxDefrowheight;  break;
    2431         [ #  # ]:          0 :         case EXC_ID_GUTS:           xRec = mxGuts;          break;
    2432         [ #  # ]:          0 :         case EXC_ID_NOTE:           xRec = mxNoteList;      break;
    2433         [ #  # ]:          0 :         case EXC_ID_MERGEDCELLS:    xRec = mxMergedcells;   break;
    2434         [ #  # ]:          0 :         case EXC_ID_HLINK:          xRec = mxHyperlinkList; break;
    2435         [ #  # ]:          0 :         case EXC_ID_DVAL:           xRec = mxDval;          break;
    2436         [ #  # ]:          0 :         case EXC_ID_EXTLST:         xRec = mxExtLst;        break;
    2437                 :            :         default:    OSL_FAIL( "XclExpCellTable::CreateRecord - unknown record id" );
    2438                 :            :     }
    2439                 :          0 :     return xRec;
    2440                 :            : }
    2441                 :            : 
    2442                 :          0 : void XclExpCellTable::Save( XclExpStream& rStrm )
    2443                 :            : {
    2444                 :            :     // DEFCOLWIDTH and COLINFOs
    2445                 :          0 :     maColInfoBfr.Save( rStrm );
    2446                 :            :     // ROWs and cell records
    2447                 :          0 :     maRowBfr.Save( rStrm );
    2448                 :          0 : }
    2449                 :            : 
    2450                 :          0 : void XclExpCellTable::SaveXml( XclExpXmlStream& rStrm )
    2451                 :            : {
    2452                 :          0 :     maColInfoBfr.SaveXml( rStrm );
    2453                 :          0 :     maRowBfr.SaveXml( rStrm );
    2454                 :          0 :     mxExtLst->SaveXml( rStrm );
    2455 [ +  - ][ +  - ]:         24 : }
    2456                 :            : 
    2457                 :            : // ============================================================================
    2458                 :            : 
    2459                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10