[ooo-build-commit] .: Branch 'ooo-build-3-2-1' - patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Wed Sep 22 08:07:06 PDT 2010


 patches/dev300/apply                              |    3 
 patches/dev300/calc-xls-import-mem-footprint.diff |  758 ++++++++++++++++++++++
 2 files changed, 761 insertions(+)

New commits:
commit 6862bcb155daa0aee1d98ed30b5c94edfa8255d7
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Sep 22 11:03:42 2010 -0400

    Reduce memory footprint during import of Excel documents.
    
    This patch cuts memory footprint of Excel import filter by roughly
    20MB per sheet, and introduces performance enhancement.
    
    With the (confidential) test document I used, the footprint dropped
    from 1.6GB to 224MB with this change, and the time it takes was cut
    by 80% to 90%. (n#637925)
    
    This patch is experimental, and is not enabled in the default build.
    
    * patches/dev300/apply:
    * patches/dev300/calc-xls-import-mem-footprint.diff:

diff --git a/patches/dev300/apply b/patches/dev300/apply
index 177ca01..704f97d 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -4129,6 +4129,9 @@ SectionOwner => kohei
 # Rework external ref token handling in interpreter, to fix OFFSET and INDIRECT.
 calc-extref-interpreter-rework.diff, n#628876, kohei
 
+# Reduce memory footprint per sheet during import of xls document.
+calc-xls-import-mem-footprint.diff, n#637925, kohei
+
 [ Netbook ]
 netbook-window-decoration-update.diff, n#621116, rodo
 
diff --git a/patches/dev300/calc-xls-import-mem-footprint.diff b/patches/dev300/calc-xls-import-mem-footprint.diff
new file mode 100644
index 0000000..fb1acc8
--- /dev/null
+++ b/patches/dev300/calc-xls-import-mem-footprint.diff
@@ -0,0 +1,758 @@
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index ad854de..cbf9dde 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -1254,13 +1254,14 @@ public:
+                     //
+ 
+     SC_DLLPUBLIC void			SetColWidth( SCCOL nCol, SCTAB nTab, USHORT nNewWidth );
++    SC_DLLPUBLIC void			SetColWidthOnly( SCCOL nCol, SCTAB nTab, USHORT nNewWidth );
+     SC_DLLPUBLIC void			SetRowHeight( SCROW nRow, SCTAB nTab, USHORT nNewHeight );
+     SC_DLLPUBLIC void			SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab,
+                                             USHORT nNewHeight );
+ 
+     SC_DLLPUBLIC void           SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab,
+                                                   USHORT nNewHeight );
+-    void			SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual );
++    SC_DLLPUBLIC void           SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual );
+ 
+     SC_DLLPUBLIC USHORT			GetColWidth( SCCOL nCol, SCTAB nTab ) const;
+     SC_DLLPUBLIC USHORT         GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero = true ) const;
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index fd59629..2572271 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -605,6 +605,7 @@ public:
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bWidth, BOOL bTotalSize );
+     void		SetColWidth( SCCOL nCol, USHORT nNewWidth );
++    void        SetColWidthOnly( SCCOL nCol, USHORT nNewWidth );
+     void		SetRowHeight( SCROW nRow, USHORT nNewHeight );
+     BOOL		SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight,
+                                     double nPPTX, double nPPTY );
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 65831a3..42afd0f 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -3122,6 +3122,11 @@ void ScDocument::SetColWidth( SCCOL nCol, SCTAB nTab, USHORT nNewWidth )
+         pTab[nTab]->SetColWidth( nCol, nNewWidth );
+ }
+ 
++void ScDocument::SetColWidthOnly( SCCOL nCol, SCTAB nTab, USHORT nNewWidth )
++{
++    if ( ValidTab(nTab) && pTab[nTab] )
++        pTab[nTab]->SetColWidthOnly( nCol, nNewWidth );
++}
+ 
+ void ScDocument::SetRowHeight( SCROW nRow, SCTAB nTab, USHORT nNewHeight )
+ {
+diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
+index bbbfeb1..9426502 100644
+--- sc/source/core/data/table2.cxx
++++ sc/source/core/data/table2.cxx
+@@ -2055,6 +2055,17 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
+     }
+ }
+ 
++void ScTable::SetColWidthOnly( SCCOL nCol, USHORT nNewWidth )
++{
++    if (!VALIDCOL(nCol) || !pColWidth)
++        return;
++
++    if (!nNewWidth)
++        nNewWidth = STD_COL_WIDTH;
++
++    if (nNewWidth != pColWidth[nCol])
++        pColWidth[nCol] = nNewWidth;
++}
+ 
+ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
+ {
+diff --git sc/source/filter/excel/colrowst.cxx sc/source/filter/excel/colrowst.cxx
+index 01587c0..00b2295 100644
+--- sc/source/filter/excel/colrowst.cxx
++++ sc/source/filter/excel/colrowst.cxx
+@@ -58,8 +58,9 @@ XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot& rRoot ) :
+     XclImpRoot( rRoot ),
+     maWidths( MAXCOLCOUNT, 0 ),
+     maColFlags( MAXCOLCOUNT, 0 ),
+-    maHeights( MAXROWCOUNT, 0 ),
+-    maRowFlags( MAXROWCOUNT, 0 ),
++    maRowHeights(0, MAXROWCOUNT, 0),
++    maRowFlags(0, MAXROWCOUNT, 0),
++    maHiddenRows(0, MAXROWCOUNT, false),
+     mnLastScRow( -1 ),
+     mnDefWidth( STD_COL_WIDTH ),
+     mnDefHeight( static_cast< sal_uInt16 >( STD_ROW_HEIGHT ) ),
+@@ -134,38 +135,59 @@ void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlag
+ 
+ void XclImpColRowSettings::SetHeight( SCROW nScRow, sal_uInt16 nHeight )
+ {
+-    if( ValidRow( nScRow ) )
+-    {
+-        sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK;
+-        bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0);
+-        maHeights[ nScRow ] = nRawHeight;
+-        sal_uInt8& rnFlags = maRowFlags[ nScRow ];
+-        ::set_flag( rnFlags, EXC_COLROW_USED );
+-        if( !bDefHeight && (nRawHeight == 0) )
+-            ::set_flag( rnFlags, EXC_COLROW_HIDDEN );
+-        ::set_flag( rnFlags, EXC_COLROW_DEFAULT, bDefHeight );
+-        if( nScRow > mnLastScRow )
+-            mnLastScRow = nScRow;
+-    }
++    if (!ValidRow(nScRow))
++        return;
++
++    sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK;
++    bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0);
++    maRowHeights.insert_back(nScRow, nScRow+1, nRawHeight);
++    sal_uInt8 nFlagVal = 0;
++    if (!maRowFlags.search(nScRow, nFlagVal))
++        return;
++
++    ::set_flag(nFlagVal, EXC_COLROW_USED);
++    ::set_flag(nFlagVal, EXC_COLROW_DEFAULT, bDefHeight);
++
++    if (!bDefHeight && nRawHeight == 0)
++        maHiddenRows.insert_back(nScRow, nScRow+1, true);
++
++    maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
++
++    if (nScRow > mnLastScRow)
++        mnLastScRow = nScRow;
+ }
+ 
+ void XclImpColRowSettings::SetRowSettings( SCROW nScRow, sal_uInt16 nHeight, sal_uInt16 nFlags )
+ {
+-    if( ValidRow( nScRow ) )
+-    {
+-        SetHeight( nScRow, nHeight );
+-        sal_uInt8& rnFlags = maRowFlags[ nScRow ];
+-        if( ::get_flag( nFlags, EXC_ROW_UNSYNCED ) )
+-            ::set_flag( rnFlags, EXC_COLROW_MAN );
+-        if( ::get_flag( nFlags, EXC_ROW_HIDDEN ) )
+-            ::set_flag( rnFlags, EXC_COLROW_HIDDEN );
+-    }
++    if (!ValidRow(nScRow))
++        return;
++
++    SetHeight(nScRow, nHeight);
++
++    sal_uInt8 nFlagVal = 0;
++    if (!maRowFlags.search(nScRow, nFlagVal))
++        return;
++
++    if (::get_flag(nFlags, EXC_ROW_UNSYNCED))
++        ::set_flag(nFlagVal, EXC_COLROW_MAN);
++
++    maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
++
++    if (::get_flag(nFlags, EXC_ROW_HIDDEN))
++        maHiddenRows.insert_back(nScRow, nScRow+1, true);
+ }
+ 
+ void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow )
+ {
+-    if( ValidRow( nScRow ) )
+-        ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_MAN );
++    if (!ValidRow(nScRow))
++        return;
++
++    sal_uInt8 nFlagVal = 0;
++    if (!maRowFlags.search(nScRow, nFlagVal))
++        return;
++
++    ::set_flag(nFlagVal, EXC_COLROW_MAN);
++    maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
+ }
+ 
+ void XclImpColRowSettings::SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex )
+@@ -201,7 +223,7 @@ void XclImpColRowSettings::Convert( SCTAB nScTab )
+             ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
+             nWidth = mnDefWidth;
+         }
+-        rDoc.SetColWidth( nScCol, nScTab, nWidth );
++        rDoc.SetColWidthOnly( nScCol, nScTab, nWidth );
+     }
+ 
+     // row heights ------------------------------------------------------------
+@@ -213,62 +235,64 @@ void XclImpColRowSettings::Convert( SCTAB nScTab )
+         rDoc.SetRowFlags( 0, MAXROW, nScTab, CR_MANUALSIZE );
+     bool bDefHideRow = ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN );
+ 
+-    SCROW nFirstScRow = -1;
+-    sal_uInt16 nLastHeight = 0;
+-    for( SCROW nScRow = 0; nScRow <= mnLastScRow ; ++nScRow )
++    maRowHeights.build_tree();
++    if (!maRowHeights.is_tree_valid())
++        return;
++
++    RowFlagsType::const_iterator itrFlags = maRowFlags.begin(), itrFlagsEnd = maRowFlags.end();
++    SCROW nPrevRow = -1;
++    sal_uInt8 nPrevFlags = 0;
++    sal_uInt16 nPrevHeight = 0;
++    for (; itrFlags != itrFlagsEnd; ++itrFlags)
+     {
+-        // get height and hidden state from cached data
+-        sal_uInt8 nFlags = maRowFlags[ nScRow ];
+-        sal_uInt16 nHeight = 0;
+-        bool bHideRow = false;
+-        if( ::get_flag( nFlags, EXC_COLROW_USED ) )
++        SCROW nRow = itrFlags->first;
++        sal_uInt8 nFlags = itrFlags->second;
++        if (nPrevRow >= 0)
+         {
+-            if( ::get_flag( nFlags, EXC_COLROW_DEFAULT ) )
+-            {
+-                nHeight = mnDefHeight;
+-                bHideRow = bDefHideRow;
+-            }
+-            else
++            sal_uInt16 nHeight = 0;
++
++            if (::get_flag(nPrevFlags, EXC_COLROW_USED))
+             {
+-                nHeight = maHeights[ nScRow ];
+-                if( nHeight == 0 )
++                if (::get_flag(nPrevFlags, EXC_COLROW_DEFAULT))
+                 {
+                     nHeight = mnDefHeight;
+-                    bHideRow = true;
++                    rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
++                }
++                else
++                {
++                    for (SCROW i = nPrevRow; i <= nRow - 1; ++i)
++                    {
++                        SCROW nLast;
++                        if (!maRowHeights.search_tree(i, nHeight, NULL, &nLast))
++                        {
++                            // search failed for some reason
++                            return;
++                        }
++
++                        if (nLast > nRow)
++                            nLast = nRow;
++
++                        rDoc.SetRowHeightOnly(i, nLast-1, nScTab, nHeight);
++                        i = nLast-1;
++                        nPrevHeight = nHeight;
++                    }
+                 }
+-            }
+ 
+-            if( ::get_flag( nFlags, EXC_COLROW_MAN ) )
+-                rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_MANUALSIZE );
+-        }
+-        else
+-        {
+-            nHeight = mnDefHeight;
+-            bHideRow = bDefHideRow;
++                if (::get_flag(nPrevFlags, EXC_COLROW_MAN))
++                    rDoc.SetManualHeight(nPrevRow, nRow-1, nScTab, true);
++            }
++            else
++            {
++                nHeight = mnDefHeight;
++                rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
++            }
++            nPrevHeight = nHeight;
+         }
+ 
+-        /*  Hidden rows: remember hidden state, but do not set hidden state in
+-            document here. Needed for #i11776#, no HIDDEN flags in the document,
+-            until filters and outlines are inserted. */
+-        if( bHideRow )
+-            ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN );
+-
+-        // set height range
+-        if( (nLastHeight != nHeight) || (nScRow == 0) )
+-        {
+-            DBG_ASSERT( (nScRow == 0) || (nFirstScRow >= 0), "XclImpColRowSettings::Convert - algorithm error" );
+-            if( nScRow > 0 )
+-                rDoc.SetRowHeightOnly( nFirstScRow, nScRow - 1, nScTab, nLastHeight );
+-
+-            nFirstScRow = nScRow;
+-            nLastHeight = nHeight;
+-        }
++        nPrevRow = nRow;
++        nPrevFlags = nFlags;
+     }
+ 
+-    // set row height of last portion
+-    if( mnLastScRow >= 0 )
+-        rDoc.SetRowHeightOnly( nFirstScRow, mnLastScRow, nScTab, nLastHeight );
+-
+     // ------------------------------------------------------------------------
+ 
+     mbDirty = false;
+@@ -298,17 +322,41 @@ void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
+         }
+     }
+ 
+-    // hide the rows
+-    for( SCROW nScRow = 0; nScRow <= mnLastScRow; ++nScRow )
++    // In case the excel row limit is lower than calc's, use the visibility of
++    // the last row and extend it to calc's last row.
++    SCROW nLastXLRow = GetRoot().GetXclMaxPos().Row();
++    if (nLastXLRow < MAXROW)
+     {
+-        if( ::get_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN ) )
++        bool bHidden = false;
++        if (!maHiddenRows.search(nLastXLRow, bHidden))
++            return;
++    
++        maHiddenRows.insert_back(nLastXLRow, MAXROWCOUNT, bHidden);
++    }
++
++    SCROW nPrevRow = -1;
++    bool bPrevHidden = false;
++    RowHiddenType::const_iterator itr = maHiddenRows.begin(), itrEnd = maHiddenRows.end();
++    for (; itr != itrEnd; ++itr)
++    {
++        SCROW nRow = itr->first;
++        bool bHidden = itr->second;
++        if (nPrevRow >= 0)
+         {
+-            // hide the row
+-            rDoc.ShowRow( nScRow, nScTab, FALSE );
+-            // #i38093# rows hidden by filter need extra flag
+-            if( (nFirstFilterScRow <= nScRow) && (nScRow <= nLastFilterScRow) )
+-                rDoc.SetRowFiltered(nScRow, nScRow, nScTab, true);
++            if (bPrevHidden)
++            {
++                rDoc.ShowRows(nPrevRow, nRow-1, nScTab, false);
++                // #i38093# rows hidden by filter need extra flag
++                if (nFirstFilterScRow <= nPrevRow && nPrevRow <= nLastFilterScRow)
++                {
++                    SCROW nLast = ::std::min(nRow-1, nLastFilterScRow);
++                    rDoc.SetRowFiltered(nPrevRow, nLast, nScTab, true);
++                }
++            }
+         }
++
++        nPrevRow = nRow;
++        bPrevHidden = bHidden;
+     }
+ 
+     // #i47438# if default row format is hidden, hide remaining rows
+diff --git sc/source/filter/excel/exctools.cxx sc/source/filter/excel/exctools.cxx
+index c9f4289..a0d32db 100644
+--- sc/source/filter/excel/exctools.cxx
++++ sc/source/filter/excel/exctools.cxx
+@@ -59,6 +59,8 @@
+ #include "xilink.hxx"
+ #include "xecontent.hxx"
+ 
++#include <vector>
++
+ // - ALLGEMEINE ----------------------------------------------------------
+ 
+ RootData::RootData( void )
+@@ -94,192 +96,93 @@ RootData::~RootData()
+ }
+ 
+ 
+-
+-
+-XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize )
++XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize ) :
++    maLevels(0, nNewSize, 0),
++    mpOutlineArray(NULL),
++    mnMaxLevel(0),
++    mbButtonAfter(true)
+ {
+-    DBG_ASSERT( nNewSize > 0, "-OutlineBuffer::Ctor: nNewSize == 0!" );
+-
+-    nSize = nNewSize + 1;
+-    pLevel = new BYTE[ nSize ];
+-    pOuted = new BOOL[ nSize ];
+-    pHidden = new BOOL[ nSize ];
+-    pOutlineArray = NULL;
+-
+-    Reset();
+ }
+ 
+-
+ XclImpOutlineBuffer::~XclImpOutlineBuffer()
+ {
+-    delete[] pLevel;
+-    delete[] pOuted;
+-    delete[] pHidden;
+ }
+ 
+-
+-void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, BYTE nVal, BOOL bOuted, BOOL bHidden )
++void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, sal_uInt8 nVal, bool bCollapsed )
+ {
+-    if( nIndex < nSize )
+-    {
+-        pLevel[ nIndex ] = nVal;
+-        pOuted[ nIndex ] = bOuted;
+-        pHidden[ nIndex ] = bHidden;
+-
+-        if( nIndex > nLast )
+-            nLast = nIndex;
+-        if( nVal > nMaxLevel )
+-            nMaxLevel = nVal;
+-    }
++    maLevels.insert_back(nIndex, nIndex+1, nVal);
++    if (nVal > mnMaxLevel)
++        mnMaxLevel = nVal;
++    if (bCollapsed)
++        maCollapsedPosSet.insert(nIndex);
+ }
+ 
+-
+ void XclImpOutlineBuffer::SetOutlineArray( ScOutlineArray* pOArray )
+ {
+-    pOutlineArray = pOArray;
++    mpOutlineArray = pOArray;
+ }
+ 
+-
+-// transtorm xcl-outline into SC-outline
+-void XclImpOutlineBuffer::MakeScOutline( void )
++void XclImpOutlineBuffer::MakeScOutline()
+ {
+-    if( !pOutlineArray || !HasOutline() )
++    if (!mpOutlineArray)
+         return;
+ 
+-    const UINT16	nNumLev			= 8;
+-    BOOL			bPreOutedLevel	= FALSE;
+-    BYTE			nCurrLevel		= 0;
+-    BOOL			bMakeHidden[ nNumLev ];
+-    BOOL			bMakeVisible[ nNumLev + 1 ];
+-
+-    sal_uInt16 nLevel;
+-    for( nLevel = 0; nLevel < nNumLev; ++nLevel )
+-        bMakeHidden[ nLevel ] = FALSE;
+-    for( nLevel = 0; nLevel <= nNumLev; ++nLevel )
+-        bMakeVisible[ nLevel ] = TRUE;
+-    if( nLast < (nSize - 1) )
+-        nLast++;
+-
+-    // search for hidden attributes at end of level, move them to begin
+-    if( bButtonNormal )
++    ::std::vector<sal_uInt8> aOutlineStack;
++    aOutlineStack.reserve(mnMaxLevel);
++    OutlineLevels::const_iterator itr = maLevels.begin(), itr_end = maLevels.end();
++    for (; itr != itr_end; ++itr)
+     {
+-        for( BYTE nWorkLevel = 1; nWorkLevel <= nMaxLevel; nWorkLevel++ )
++        SCSIZE nPos = itr->first;
++        sal_uInt8 nLevel = itr->second;
++        sal_uInt8 nCurLevel = static_cast<sal_uInt8>(aOutlineStack.size());
++        if (nLevel > nCurLevel)
+         {
+-            UINT16	nStartPos       = 0;
+-            BYTE    nCurrLevel2 = 0;
+-            BYTE	nPrevLevel	= 0;
+-
+-            for( SCSIZE nC = 0 ; nC <= nLast ; nC++ )
++            for (sal_uInt8 i = 0; i < nLevel - nCurLevel; ++i)
++                aOutlineStack.push_back(nPos);
++        }
++        else
++        {
++            DBG_ASSERT(nLevel < nCurLevel, "XclImpOutlineBuffer::MakeScOutline: unexpected level!");
++            for (sal_uInt8 i = 0; i < nCurLevel - nLevel; ++i)
+             {
+-                nPrevLevel = nCurrLevel2;
+-                nCurrLevel2 = pLevel[ nC ];
+-                if( (nPrevLevel < nWorkLevel) && (nCurrLevel2 >= nWorkLevel) )
+-                    nStartPos = static_cast< sal_uInt16 >( nC );
+-                else if( (nPrevLevel >= nWorkLevel) && (nCurrLevel2 < nWorkLevel) )
++                if (aOutlineStack.empty())
+                 {
+-                    if( pOuted[ nC ] && pHidden[ nStartPos ] )
+-                    {
+-                        if( nStartPos )
+-                            pOuted[ nStartPos - 1 ] = TRUE;
+-                        else
+-                            bPreOutedLevel = TRUE;
+-                        pOuted[ nC ] = FALSE;
+-                    }
++                    // Something is wrong.
++                    return;
+                 }
++                SCSIZE nFirstPos = aOutlineStack.back();
++                sal_uInt8 nThisLevel = static_cast<sal_uInt8>(aOutlineStack.size());
++                aOutlineStack.pop_back();
++                bool bCollapsed = false;
++                if (mbButtonAfter)
++                    bCollapsed = maCollapsedPosSet.count(nPos) > 0;
++                else if (nFirstPos > 0)
++                    bCollapsed = maCollapsedPosSet.count(nFirstPos-1) > 0;
++
++                BOOL bDummy;
++                mpOutlineArray->Insert(nFirstPos, nPos-1, bDummy, bCollapsed);
+             }
+         }
+     }
+-    else
+-        bPreOutedLevel = pHidden[ 0 ];
+-
+-    // generate SC outlines
+-    UINT16	nPrevC;
+-    UINT16	nStart[ nNumLev ];
+-    BOOL	bDummy;
+-    BOOL	bPrevOuted	= bPreOutedLevel;
+-    BOOL	bCurrHidden = FALSE;
+-    BOOL	bPrevHidden = FALSE;
+-
+-    for( SCSIZE nC = 0; nC <= nLast; nC++ )
+-    {
+-        BYTE nWorkLevel = pLevel[ nC ];
+-
+-        nPrevC      = static_cast< sal_uInt16 >( nC ? nC - 1 : 0 );
+-        bPrevHidden	= bCurrHidden;
+-        bCurrHidden	= pHidden[ nC ];
+-
+-        // open new levels
+-        while( nWorkLevel > nCurrLevel )
+-        {
+-            nCurrLevel++;
+-            bMakeHidden[ nCurrLevel ] = bPrevOuted;
+-            bMakeVisible[ nCurrLevel + 1 ] =
+-                bMakeVisible[ nCurrLevel ] && !bMakeHidden[ nCurrLevel ];
+-            nStart[ nCurrLevel ] = static_cast< sal_uInt16 >( nC );
+-        }
+-        // close levels
+-        while( nWorkLevel < nCurrLevel )
+-        {
+-            BOOL bLastLevel		= (nWorkLevel == (nCurrLevel - 1));
+-            BOOL bRealHidden	= (bMakeHidden[ nCurrLevel ] && bPrevHidden );
+-            BOOL bRealVisible	= (bMakeVisible[ nCurrLevel ] ||
+-                                    (!bCurrHidden && bLastLevel));
+-
+-            pOutlineArray->Insert( nStart[ nCurrLevel ], nPrevC , bDummy,
+-                bRealHidden, bRealVisible );
+-            nCurrLevel--;
+-        }
+-
+-        bPrevOuted = pOuted[ nC ];
+-    }
+ }
+ 
+-
+-void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, BYTE nVal,
+-                                    BOOL bOuted, BOOL bHidden )
++void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal, bool bCollapsed )
+ {
+-    DBG_ASSERT( nF <= nL, "+OutlineBuffer::SetLevelRange(): Last < First!" );
+-
+-    if( nL < nSize )
+-    {
+-        if( nL > nLast )
+-            nLast = nL;
+-
+-        BYTE*	pLevelCount;
+-        BYTE*	pLast;
+-        BOOL*	pOutedCount;
+-        BOOL*	pHiddenCount;
++    if (nF > nL)
++        // invalid range
++        return;
+ 
+-        pLevelCount = &pLevel[ nF ];
+-        pLast = &pLevel[ nL ];
+-        pOutedCount = &pOuted[ nF ];
+-        pHiddenCount = &pHidden[ nF ];
++    maLevels.insert_back(nF, nL+1, nVal);
+ 
+-        while( pLevelCount <= pLast )
+-        {
+-            *( pLevelCount++ ) = nVal;
+-            *( pOutedCount++ ) = bOuted;
+-            *( pHiddenCount++ ) = bHidden;
+-        }
+-
+-        if( nVal > nMaxLevel )
+-            nMaxLevel = nVal;
+-    }
++    if (bCollapsed)
++        maCollapsedPosSet.insert(nF);
+ }
+ 
+-
+-void XclImpOutlineBuffer::Reset( void )
++void XclImpOutlineBuffer::SetButtonMode( bool bRightOrUnder )
+ {
+-    for( SCSIZE nC = 0 ; nC < nSize ; nC++  )
+-    {
+-        pLevel[ nC ] = 0;
+-        pOuted[ nC ] = pHidden[ nC ] = FALSE;
+-    }
+-    nLast = 0;
+-    nMaxLevel = 0;
++    mbButtonAfter = bRightOrUnder;
+ }
+ 
+-
+ //___________________________________________________________________
+ 
+ 
+diff --git sc/source/filter/excel/impop.cxx sc/source/filter/excel/impop.cxx
+index e9e3a39..facd4a0 100644
+--- sc/source/filter/excel/impop.cxx
++++ sc/source/filter/excel/impop.cxx
+@@ -403,9 +403,7 @@ void ImportExcel::Row25( void )
+             aIn >> nGrbit;
+ 
+             sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+-            pRowOutlineBuff->SetLevel( nRow, nLevel,
+-                ::get_flag( nGrbit, EXC_ROW_COLLAPSED ), ::get_flag( nGrbit, EXC_ROW_HIDDEN ) );
+-
++            pRowOutlineBuff->SetLevel( nRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
+             pColRowBuff->SetRowSettings( nRow, nRowHeight, nGrbit );
+         }
+     }
+@@ -666,7 +664,7 @@ void ImportExcel::Colinfo( void )
+     bool bHidden = ::get_flag( nOpt, EXC_COLINFO_HIDDEN );
+     bool bCollapsed = ::get_flag( nOpt, EXC_COLINFO_COLLAPSED );
+     sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nOpt, 8, 3 );
+-    pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed, bHidden );
++    pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed );
+ 
+     if( bHidden )
+         pColRowBuff->HideColRange( nColFirst, nColLast );
+@@ -942,9 +940,7 @@ void ImportExcel::Row34( void )
+         aIn >> nGrbit >> nXF;
+ 
+         sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+-        pRowOutlineBuff->SetLevel( nScRow, nLevel,
+-            ::get_flag( nGrbit, EXC_ROW_COLLAPSED ), ::get_flag( nGrbit, EXC_ROW_HIDDEN ) );
+-
++        pRowOutlineBuff->SetLevel( nScRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
+         pColRowBuff->SetRowSettings( nScRow, nRowHeight, nGrbit );
+ 
+         if( nGrbit & EXC_ROW_USEDEFXF )
+diff --git sc/source/filter/inc/colrowst.hxx sc/source/filter/inc/colrowst.hxx
+index 325d380..a82cf13 100644
+--- sc/source/filter/inc/colrowst.hxx
++++ sc/source/filter/inc/colrowst.hxx
+@@ -29,6 +29,10 @@
+ #define SC_COLROWST_HXX
+ 
+ #include "xiroot.hxx"
++#include <mdds/flat_segment_tree.hpp>
++
++#define XLS_USE_NEW_ROW_CONT 1
++
+ 
+ class XclImpStream;
+ 
+@@ -59,8 +63,13 @@ public:
+ private:
+     ScfUInt16Vec        maWidths;           /// Column widths in twips.
+     ScfUInt8Vec         maColFlags;         /// Flags for all columns.
+-    ScfUInt16Vec        maHeights;          /// Row heights in twips.
+-    ScfUInt8Vec         maRowFlags;         /// Flags for all rows.
++                                            ///
++    typedef ::mdds::flat_segment_tree<SCROW, sal_uInt16> RowHeightsType;
++    typedef ::mdds::flat_segment_tree<SCROW, sal_uInt8>  RowFlagsType;
++    typedef ::mdds::flat_segment_tree<SCROW, bool>       RowHiddenType;
++    RowHeightsType      maRowHeights;
++    RowFlagsType        maRowFlags;
++    RowHiddenType       maHiddenRows;
+ 
+     SCROW               mnLastScRow;
+ 
+diff --git sc/source/filter/inc/otlnbuff.hxx sc/source/filter/inc/otlnbuff.hxx
+index 599e7df..e72f010 100644
+--- sc/source/filter/inc/otlnbuff.hxx
++++ sc/source/filter/inc/otlnbuff.hxx
+@@ -29,50 +29,31 @@
+ #define SC_OTLNBUFF_HXX
+ 
+ #include <tools/solar.h>
++#include <mdds/flat_segment_tree.hpp>
++#include <set>
+ 
+ class ScOutlineArray;
+ 
+ class XclImpOutlineBuffer
+ {
+-    // -> exctools.cxx
+-    private:
+-        BYTE*			pLevel;
+-        BOOL*			pOuted;
+-        BOOL*			pHidden;
+-        SCSIZE			nSize;
+-        SCSIZE			nLast;
+-        BYTE			nMaxLevel;
+-        ScOutlineArray*	pOutlineArray;
+-        BOOL			bButtonNormal;	// TRUE -> right / under
+-    public:
+-                        XclImpOutlineBuffer( SCSIZE nNewSize );
+-                        ~XclImpOutlineBuffer();
+-        void			SetLevel( SCSIZE nIndex, BYTE nVal, BOOL bOuted, BOOL bHidden );
+-        void			SetOutlineArray( ScOutlineArray* pOArray );
+-        void			Reset( void );
+-        void			MakeScOutline( void );
+-        void			SetLevelRange( SCSIZE nF, SCSIZE nL, BYTE nVal,
+-                            BOOL bOuted, BOOL bHidden );
+-
+-        inline BOOL		HasOutline( void ) const;
+-
+-        inline void		SetButtonMode( const BOOL bRightOrUnder );
++public:
++    XclImpOutlineBuffer( SCSIZE nNewSize );
++    ~XclImpOutlineBuffer();
++
++    void SetLevel( SCSIZE nIndex, sal_uInt8 nVal, bool bCollapsed );
++    void SetOutlineArray( ScOutlineArray* pOArray );
++    void MakeScOutline();
++    void SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal, bool bCollapsed );
++    void SetButtonMode( bool bRightOrUnder );
++
++private:
++    typedef ::mdds::flat_segment_tree<SCSIZE, sal_uInt8> OutlineLevels;
++    OutlineLevels       maLevels;
++    ::std::set<SCSIZE>  maCollapsedPosSet;
++    ScOutlineArray*     mpOutlineArray;
++    sal_uInt8           mnMaxLevel;
++    bool                mbButtonAfter:1;
+ };
+ 
+-
+-
+-
+-inline BOOL XclImpOutlineBuffer::HasOutline( void ) const
+-{
+-    return nMaxLevel > 0;
+-}
+-
+-
+-inline void XclImpOutlineBuffer::SetButtonMode( const BOOL b )
+-{
+-    bButtonNormal = b;
+-}
+-
+-
+ #endif
+ 
+diff --git sc/source/filter/xlsx/xlsx-exctools.cxx sc/source/filter/xlsx/xlsx-exctools.cxx
+index 58b0973..2e6484c 100644
+--- sc/source/filter/xlsx/xlsx-exctools.cxx
++++ sc/source/filter/xlsx/xlsx-exctools.cxx
+@@ -97,7 +97,7 @@ RootData::~RootData()
+ }
+ 
+ 
+-
++#if 0
+ 
+ XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize )
+ {
+@@ -282,6 +282,7 @@ void XclImpOutlineBuffer::Reset( void )
+     nMaxLevel = 0;
+ }
+ 
++#endif
+ 
+ //___________________________________________________________________
+ 


More information about the ooo-build-commit mailing list