[ooo-build-commit] .: 3 commits - sc/inc sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Mon Oct 4 11:20:25 PDT 2010


 sc/inc/attarray.hxx                            |    1 
 sc/inc/column.hxx                              |    2 
 sc/inc/document.hxx                            |    4 
 sc/inc/simplerangelist.hxx                     |   82 ++++++++
 sc/inc/table.hxx                               |    2 
 sc/source/core/data/attarray.cxx               |   15 +
 sc/source/core/data/column.cxx                 |    4 
 sc/source/core/data/document.cxx               |    8 
 sc/source/core/data/table2.cxx                 |    8 
 sc/source/core/tool/makefile.mk                |    2 
 sc/source/core/tool/simplerangelist.cxx        |  243 ++++++++++++++++++++++++
 sc/source/filter/excel/excimp8.cxx             |    3 
 sc/source/filter/excel/read.cxx                |    5 
 sc/source/filter/excel/xicontent.cxx           |  245 +++++++++++++------------
 sc/source/filter/excel/xiroot.cxx              |    7 
 sc/source/filter/excel/xistyle.cxx             |  107 ++++++++--
 sc/source/filter/inc/xicontent.hxx             |   25 ++
 sc/source/filter/inc/xiroot.hxx                |    5 
 sc/source/filter/inc/xistyle.hxx               |   20 --
 sc/source/filter/xml/XMLStylesImportHelper.cxx |  218 +++++++++++++---------
 sc/source/filter/xml/XMLStylesImportHelper.hxx |   28 +-
 21 files changed, 774 insertions(+), 260 deletions(-)

New commits:
commit 7a0b5870500e035f9916778f2d98f6bd68a1a698
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Oct 4 14:14:38 2010 -0400

    And several fixes against the previous commit wrt xls import perf.

diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
index a601d76..59bb30c 100644
--- a/sc/source/filter/excel/excimp8.cxx
+++ b/sc/source/filter/excel/excimp8.cxx
@@ -250,8 +250,9 @@ void ImportExcel8::ReadBasic( void )
 
 void ImportExcel8::EndSheet( void )
 {
-    GetCondFormatManager().Apply();
     ImportExcel::EndSheet();
+    GetCondFormatManager().Apply();
+    GetValidationManager().Apply();
 }
 
 
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index 5b67513..2f179e8 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -803,6 +803,7 @@ FltError ImportExcel8::Read( void )
     XclImpObjectManager&    rObjMgr         = GetObjectManager();
     // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets)
     XclImpCondFormatManager& rCondFmtMgr    = GetCondFormatManager();
+    XclImpValidationManager& rValidMgr      = GetValidationManager();
     XclImpPivotTableManager& rPTableMgr     = GetPivotTableManager();
     XclImpWebQueryBuffer&   rWQBfr          = GetWebQueryBuffer();
 
@@ -1176,8 +1177,8 @@ FltError ImportExcel8::Read( void )
                     case EXC_ID_CONDFMT:        rCondFmtMgr.ReadCondfmt( maStrm );      break;
                     case EXC_ID_CF:             rCondFmtMgr.ReadCF( maStrm );           break;
 
-                    case EXC_ID_DVAL:           XclImpValidation::ReadDval( maStrm );   break;
-                    case EXC_ID_DV:             XclImpValidation::ReadDV( maStrm );     break;
+                    case EXC_ID_DVAL:           rValidMgr.ReadDval( maStrm );           break;
+                    case EXC_ID_DV:             rValidMgr.ReadDV( maStrm );             break;
 
                     case EXC_ID_QSI:            rWQBfr.ReadQsi( maStrm );               break;
                     case EXC_ID_WQSTRING:       rWQBfr.ReadWqstring( maStrm );          break;
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
index 1b3efb2..9652b17 100644
--- a/sc/source/filter/excel/xicontent.cxx
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -699,7 +699,15 @@ void XclImpCondFormatManager::Apply()
 
 // Data Validation ============================================================
 
-void XclImpValidation::ReadDval( XclImpStream& rStrm )
+XclImpValidationManager::DVItem::DVItem( const ScRangeList& rRanges, const ScValidationData& rValidData ) :
+    maRanges(rRanges), maValidData(rValidData) {}
+
+XclImpValidationManager::XclImpValidationManager( const XclImpRoot& rRoot ) :
+    XclImpRoot( rRoot )
+{
+}
+
+void XclImpValidationManager::ReadDval( XclImpStream& rStrm )
 {
     const XclImpRoot& rRoot = rStrm.GetRoot();
     DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
@@ -714,7 +722,7 @@ void XclImpValidation::ReadDval( XclImpStream& rStrm )
     }
 }
 
-void XclImpValidation::ReadDV( XclImpStream& rStrm )
+void XclImpValidationManager::ReadDV( XclImpStream& rStrm )
 {
     const XclImpRoot& rRoot = rStrm.GetRoot();
     DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
@@ -738,130 +746,145 @@ void XclImpValidation::ReadDV( XclImpStream& rStrm )
     rStrm.SetNulSubstChar();    // back to default
 
     // formula(s)
-    if( rStrm.GetRecLeft() > 8 )
+    if ( rStrm.GetRecLeft() <= 8 )
+        // Not enough bytes left in the record.  Bail out.
+        return;
+
+    sal_uInt16 nLen;
+
+    // first formula
+    // string list is single tStr token with NUL separators -> replace them with LF
+    rStrm.SetNulSubstChar( '\n' );
+    ::std::auto_ptr< ScTokenArray > xTokArr1;
+    rStrm >> nLen;
+    rStrm.Ignore( 2 );
+    if( nLen > 0 )
     {
-        sal_uInt16 nLen;
+        const ScTokenArray* pTokArr = 0;
+        rFmlaConv.Reset();
+        rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+        // formula converter owns pTokArr -> create a copy of the token array
+        if( pTokArr )
+            xTokArr1.reset( pTokArr->Clone() );
+    }
+    rStrm.SetNulSubstChar();    // back to default
 
-        // first formula
-        // string list is single tStr token with NUL separators -> replace them with LF
-        rStrm.SetNulSubstChar( '\n' );
-        ::std::auto_ptr< ScTokenArray > xTokArr1;
-        rStrm >> nLen;
-        rStrm.Ignore( 2 );
-        if( nLen > 0 )
-        {
-            const ScTokenArray* pTokArr = 0;
-            rFmlaConv.Reset();
-            rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
-            // formula converter owns pTokArr -> create a copy of the token array
-            if( pTokArr )
-                xTokArr1.reset( pTokArr->Clone() );
-        }
-        rStrm.SetNulSubstChar();    // back to default
+    // second formula
+    ::std::auto_ptr< ScTokenArray > xTokArr2;
+    rStrm >> nLen;
+    rStrm.Ignore( 2 );
+    if( nLen > 0 )
+    {
+        const ScTokenArray* pTokArr = 0;
+        rFmlaConv.Reset();
+        rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+        // formula converter owns pTokArr -> create a copy of the token array
+        if( pTokArr )
+            xTokArr2.reset( pTokArr->Clone() );
+    }
 
-        // second formula
-        ::std::auto_ptr< ScTokenArray > xTokArr2;
-        rStrm >> nLen;
-        rStrm.Ignore( 2 );
-        if( nLen > 0 )
-        {
-            const ScTokenArray* pTokArr = 0;
-            rFmlaConv.Reset();
-            rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
-            // formula converter owns pTokArr -> create a copy of the token array
-            if( pTokArr )
-                xTokArr2.reset( pTokArr->Clone() );
-        }
+    // read all cell ranges
+    XclRangeList aXclRanges;
+    rStrm >> aXclRanges;
 
-        // read all cell ranges
-        XclRangeList aXclRanges;
-        rStrm >> aXclRanges;
+    // convert to Calc range list
+    ScRangeList aScRanges;
+    rRoot.GetAddressConverter().ConvertRangeList( aScRanges, aXclRanges, nScTab, true );
 
-        // convert to Calc range list
-        ScRangeList aScRanges;
-        rRoot.GetAddressConverter().ConvertRangeList( aScRanges, aXclRanges, nScTab, true );
+    // only continue if there are valid ranges
+    if ( !aScRanges.Count() )
+        return;
 
-        // only continue if there are valid ranges
-        if( aScRanges.Count() )
-        {
-            bool bIsValid = true;   // valid settings in flags field
+    bool bIsValid = true;   // valid settings in flags field
 
-            ScValidationMode eValMode = SC_VALID_ANY;
-            switch( nFlags & EXC_DV_MODE_MASK )
-            {
-                case EXC_DV_MODE_ANY:       eValMode = SC_VALID_ANY;        break;
-                case EXC_DV_MODE_WHOLE:     eValMode = SC_VALID_WHOLE;      break;
-                case EXC_DV_MODE_DECIMAL:   eValMode = SC_VALID_DECIMAL;    break;
-                case EXC_DV_MODE_LIST:      eValMode = SC_VALID_LIST;       break;
-                case EXC_DV_MODE_DATE:      eValMode = SC_VALID_DATE;       break;
-                case EXC_DV_MODE_TIME:      eValMode = SC_VALID_TIME;       break;
-                case EXC_DV_MODE_TEXTLEN:   eValMode = SC_VALID_TEXTLEN;    break;
-                case EXC_DV_MODE_CUSTOM:    eValMode = SC_VALID_CUSTOM;     break;
-                default:                    bIsValid = false;
-            }
-            rRoot.GetTracer().TraceDVType(eValMode == SC_VALID_CUSTOM);
+    ScValidationMode eValMode = SC_VALID_ANY;
+    switch( nFlags & EXC_DV_MODE_MASK )
+    {
+        case EXC_DV_MODE_ANY:       eValMode = SC_VALID_ANY;        break;
+        case EXC_DV_MODE_WHOLE:     eValMode = SC_VALID_WHOLE;      break;
+        case EXC_DV_MODE_DECIMAL:   eValMode = SC_VALID_DECIMAL;    break;
+        case EXC_DV_MODE_LIST:      eValMode = SC_VALID_LIST;       break;
+        case EXC_DV_MODE_DATE:      eValMode = SC_VALID_DATE;       break;
+        case EXC_DV_MODE_TIME:      eValMode = SC_VALID_TIME;       break;
+        case EXC_DV_MODE_TEXTLEN:   eValMode = SC_VALID_TEXTLEN;    break;
+        case EXC_DV_MODE_CUSTOM:    eValMode = SC_VALID_CUSTOM;     break;
+        default:                    bIsValid = false;
+    }
+    rRoot.GetTracer().TraceDVType(eValMode == SC_VALID_CUSTOM);
 
-            ScConditionMode eCondMode = SC_COND_BETWEEN;
-            switch( nFlags & EXC_DV_COND_MASK )
-            {
-                case EXC_DV_COND_BETWEEN:   eCondMode = SC_COND_BETWEEN;    break;
-                case EXC_DV_COND_NOTBETWEEN:eCondMode = SC_COND_NOTBETWEEN; break;
-                case EXC_DV_COND_EQUAL:     eCondMode = SC_COND_EQUAL;      break;
-                case EXC_DV_COND_NOTEQUAL:  eCondMode = SC_COND_NOTEQUAL;   break;
-                case EXC_DV_COND_GREATER:   eCondMode = SC_COND_GREATER;    break;
-                case EXC_DV_COND_LESS:      eCondMode = SC_COND_LESS;       break;
-                case EXC_DV_COND_EQGREATER: eCondMode = SC_COND_EQGREATER;  break;
-                case EXC_DV_COND_EQLESS:    eCondMode = SC_COND_EQLESS;     break;
-                default:                    bIsValid = false;
-            }
+    ScConditionMode eCondMode = SC_COND_BETWEEN;
+    switch( nFlags & EXC_DV_COND_MASK )
+    {
+        case EXC_DV_COND_BETWEEN:   eCondMode = SC_COND_BETWEEN;    break;
+        case EXC_DV_COND_NOTBETWEEN:eCondMode = SC_COND_NOTBETWEEN; break;
+        case EXC_DV_COND_EQUAL:     eCondMode = SC_COND_EQUAL;      break;
+        case EXC_DV_COND_NOTEQUAL:  eCondMode = SC_COND_NOTEQUAL;   break;
+        case EXC_DV_COND_GREATER:   eCondMode = SC_COND_GREATER;    break;
+        case EXC_DV_COND_LESS:      eCondMode = SC_COND_LESS;       break;
+        case EXC_DV_COND_EQGREATER: eCondMode = SC_COND_EQGREATER;  break;
+        case EXC_DV_COND_EQLESS:    eCondMode = SC_COND_EQLESS;     break;
+        default:                    bIsValid = false;
+    }
 
-            if( bIsValid )
-            {
-                // first range for base address for relative references
-                const ScRange& rScRange = *aScRanges.GetObject( 0 );    // aScRanges is not empty
+    if ( !bIsValid )
+        // No valid validation found.  Bail out.
+        return;
 
-                // process string list of a list validity (convert to list of string tokens)
-                if( xTokArr1.get() && (eValMode == SC_VALID_LIST) && ::get_flag( nFlags, EXC_DV_STRINGLIST ) )
-                    XclTokenArrayHelper::ConvertStringToList( *xTokArr1, '\n', true );
 
-                ScValidationData aValidData( eValMode, eCondMode, xTokArr1.get(), xTokArr2.get(), &rDoc, rScRange.aStart );
+    // first range for base address for relative references
+    const ScRange& rScRange = *aScRanges.GetObject( 0 );    // aScRanges is not empty
 
-                aValidData.SetIgnoreBlank( ::get_flag( nFlags, EXC_DV_IGNOREBLANK ) );
-                aValidData.SetListType( ::get_flagvalue( nFlags, EXC_DV_SUPPRESSDROPDOWN, ValidListType::INVISIBLE, ValidListType::UNSORTED ) );
+    // process string list of a list validity (convert to list of string tokens)
+    if( xTokArr1.get() && (eValMode == SC_VALID_LIST) && ::get_flag( nFlags, EXC_DV_STRINGLIST ) )
+        XclTokenArrayHelper::ConvertStringToList( *xTokArr1, '\n', true );
 
-                // *** prompt box ***
-                if( aPromptTitle.Len() || aPromptMessage.Len() )
-                {
-                    // set any text stored in the record
-                    aValidData.SetInput( aPromptTitle, aPromptMessage );
-                    if( !::get_flag( nFlags, EXC_DV_SHOWPROMPT ) )
-                        aValidData.ResetInput();
-                }
+    maDVItems.push_back(
+        new DVItem(aScRanges, ScValidationData(eValMode, eCondMode, xTokArr1.get(), xTokArr2.get(), &rDoc, rScRange.aStart)));
+    DVItem& rItem = maDVItems.back();
 
-                // *** error box ***
-                ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
-                switch( nFlags & EXC_DV_ERROR_MASK )
-                {
-                    case EXC_DV_ERROR_WARNING:  eErrStyle = SC_VALERR_WARNING;  break;
-                    case EXC_DV_ERROR_INFO:     eErrStyle = SC_VALERR_INFO;     break;
-                }
-                // set texts and error style
-                aValidData.SetError( aErrorTitle, aErrorMessage, eErrStyle );
-                if( !::get_flag( nFlags, EXC_DV_SHOWERROR ) )
-                    aValidData.ResetError();
-
-                // set the handle ID
-                ULONG nHandle = rDoc.AddValidationEntry( aValidData );
-                ScPatternAttr aPattern( rDoc.GetPool() );
-                aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nHandle ) );
-
-                // apply all ranges
-                for( const ScRange* pScRange = aScRanges.First(); pScRange; pScRange = aScRanges.Next() )
-                    rDoc.ApplyPatternAreaTab( pScRange->aStart.Col(), pScRange->aStart.Row(),
-                        pScRange->aEnd.Col(), pScRange->aEnd.Row(), nScTab, aPattern );
-            }
-        }
+    rItem.maValidData.SetIgnoreBlank( ::get_flag( nFlags, EXC_DV_IGNOREBLANK ) );
+    rItem.maValidData.SetListType( ::get_flagvalue( nFlags, EXC_DV_SUPPRESSDROPDOWN, ValidListType::INVISIBLE, ValidListType::UNSORTED ) );
+
+    // *** prompt box ***
+    if( aPromptTitle.Len() || aPromptMessage.Len() )
+    {
+        // set any text stored in the record
+        rItem.maValidData.SetInput( aPromptTitle, aPromptMessage );
+        if( !::get_flag( nFlags, EXC_DV_SHOWPROMPT ) )
+            rItem.maValidData.ResetInput();
+    }
+
+    // *** error box ***
+    ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
+    switch( nFlags & EXC_DV_ERROR_MASK )
+    {
+        case EXC_DV_ERROR_WARNING:  eErrStyle = SC_VALERR_WARNING;  break;
+        case EXC_DV_ERROR_INFO:     eErrStyle = SC_VALERR_INFO;     break;
+    }
+    // set texts and error style
+    rItem.maValidData.SetError( aErrorTitle, aErrorMessage, eErrStyle );
+    if( !::get_flag( nFlags, EXC_DV_SHOWERROR ) )
+        rItem.maValidData.ResetError();
+}
+
+void XclImpValidationManager::Apply()
+{
+    ScDocument& rDoc = GetRoot().GetDoc();
+    DVItemList::iterator itr = maDVItems.begin(), itrEnd = maDVItems.end();
+    for (; itr != itrEnd; ++itr)
+    {
+        DVItem& rItem = *itr;
+        // set the handle ID
+        ULONG nHandle = rDoc.AddValidationEntry( rItem.maValidData );
+        ScPatternAttr aPattern( rDoc.GetPool() );
+        aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nHandle ) );
+
+        // apply all ranges
+        for( const ScRange* pScRange = rItem.maRanges.First(); pScRange; pScRange = rItem.maRanges.Next() )
+            rDoc.ApplyPatternAreaTab( pScRange->aStart.Col(), pScRange->aStart.Row(),
+                pScRange->aEnd.Col(), pScRange->aEnd.Row(), pScRange->aStart.Tab(), aPattern );
     }
+    maDVItems.clear();
 }
 
 // Web queries ================================================================
diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx
index 29822a7..31d365c 100644
--- a/sc/source/filter/excel/xiroot.cxx
+++ b/sc/source/filter/excel/xiroot.cxx
@@ -82,6 +82,7 @@ XclImpRoot::XclImpRoot( XclImpRootData& rImpRootData ) :
         mrImpData.mxLinkMgr.reset( new XclImpLinkManager( GetRoot() ) );
         mrImpData.mxSst.reset( new XclImpSst( GetRoot() ) );
         mrImpData.mxCondFmtMgr.reset( new XclImpCondFormatManager( GetRoot() ) );
+        mrImpData.mxValidMgr.reset( new XclImpValidationManager( GetRoot() ) );
         // TODO still in old RootData (deleted by RootData)
         GetOldRoot().pAutoFilterBuffer = new XclImpAutoFilterBuffer;
         mrImpData.mxWebQueryBfr.reset( new XclImpWebQueryBuffer( GetRoot() ) );
@@ -221,6 +222,12 @@ XclImpCondFormatManager& XclImpRoot::GetCondFormatManager() const
     return *mrImpData.mxCondFmtMgr;
 }
 
+XclImpValidationManager& XclImpRoot::GetValidationManager() const
+{
+    DBG_ASSERT( mrImpData.mxValidMgr.is(), "XclImpRoot::GetValidationManager - invalid call, wrong BIFF" );
+    return *mrImpData.mxValidMgr;
+}
+
 XclImpAutoFilterBuffer& XclImpRoot::GetFilterManager() const
 {
     // TODO still in old RootData
diff --git a/sc/source/filter/inc/xicontent.hxx b/sc/source/filter/inc/xicontent.hxx
index d8b1ec9..976dbdb 100644
--- a/sc/source/filter/inc/xicontent.hxx
+++ b/sc/source/filter/inc/xicontent.hxx
@@ -33,8 +33,10 @@
 #include "xlcontent.hxx"
 #include "xistring.hxx"
 #include "xiroot.hxx"
+#include "validat.hxx"
 
 #include <map>
+#include <boost/ptr_container/ptr_vector.hpp>
 
 /* ============================================================================
 Classes to import the big Excel document contents (related to several cells or
@@ -162,14 +164,29 @@ private:
 
 // Data Validation ============================================================
 
-/** Provides importing validation data and inserting it into a document. */
-class XclImpValidation : ScfNoInstance
+/** Imports validation data. */
+class XclImpValidationManager : protected XclImpRoot
 {
 public:
+    explicit            XclImpValidationManager( const XclImpRoot& rRoot );
+
     /** Reads a DVAL record and sets marks the dropdown arrow control to be ignored. */
-    static void         ReadDval( XclImpStream& rStrm );
+    void                ReadDval( XclImpStream& rStrm );
     /** Reads a DV record and inserts validation data into the document. */
-    static void         ReadDV( XclImpStream& rStrm );
+    void                ReadDV( XclImpStream& rStrm );
+
+    void                Apply();
+private:
+    struct DVItem
+    {
+        ScRangeList         maRanges;
+        ScValidationData    maValidData;
+
+        explicit DVItem ( const ScRangeList& rRanges, const ScValidationData& rValidData );
+    };
+    typedef ::boost::ptr_vector<DVItem> DVItemList;
+
+    DVItemList maDVItems;
 };
 
 // Web queries ================================================================
diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx
index 4d811ae..9937a71 100644
--- a/sc/source/filter/inc/xiroot.hxx
+++ b/sc/source/filter/inc/xiroot.hxx
@@ -53,6 +53,7 @@ class XclImpLinkManager;
 class XclImpObjectManager;
 class XclImpSheetDrawing;
 class XclImpCondFormatManager;
+class XclImpValidationManager;
 class XclImpAutoFilterBuffer;
 class XclImpWebQueryBuffer;
 class XclImpPivotTableManager;
@@ -82,6 +83,7 @@ struct XclImpRootData : public XclRootData
     typedef ScfRef< XclImpLinkManager >         XclImpLinkMgrRef;
     typedef ScfRef< XclImpObjectManager >       XclImpObjectMgrRef;
     typedef ScfRef< XclImpCondFormatManager >   XclImpCondFmtMgrRef;
+    typedef ScfRef< XclImpValidationManager >   XclImpValidationMgrRef;
     typedef ScfRef< XclImpWebQueryBuffer >      XclImpWebQueryBfrRef;
     typedef ScfRef< XclImpPivotTableManager >   XclImpPTableMgrRef;
     typedef ScfRef< XclImpPageSettings >        XclImpPageSettRef;
@@ -106,6 +108,7 @@ struct XclImpRootData : public XclRootData
 
     XclImpObjectMgrRef  mxObjMgr;           /// All drawing objects.
     XclImpCondFmtMgrRef mxCondFmtMgr;       /// Conditional formattings.
+    XclImpValidationMgrRef mxValidMgr;      /// Data validation
     XclImpWebQueryBfrRef mxWebQueryBfr;     /// All web queries.
     XclImpPTableMgrRef  mxPTableMgr;        /// All pivot tables and pivot caches.
 
@@ -182,6 +185,8 @@ public:
     XclImpSheetDrawing& GetCurrSheetDrawing() const;
     /** Returns the conditional formattings manager. */
     XclImpCondFormatManager& GetCondFormatManager() const;
+
+    XclImpValidationManager& GetValidationManager() const;
     /** Returns the filter manager. */
     XclImpAutoFilterBuffer& GetFilterManager() const;
     /** Returns the web query buffer. */
commit 05d67b3436f17455a63ef7df11d5595ae43a66fc
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Oct 4 14:12:42 2010 -0400

    Ported calc-perf-xls-import-cellstyles.diff from ooo-build.
    
    Like the previous commit, this one improves performance of large
    xls files.

diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx
index d3de8c8..938c2b7 100644
--- a/sc/inc/attarray.hxx
+++ b/sc/inc/attarray.hxx
@@ -133,6 +133,7 @@ public:
     void	ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet* pStyle );
     void	ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache,
                             ScEditDataArray* pDataArray = NULL );
+    bool    SetAttrEntries(ScAttrEntry* pNewData, SCSIZE nSize);
     void	ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
                                 const SvxBorderLine* pLine, BOOL bColorOnly );
 
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 3be2ed0..c088234 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -51,6 +51,7 @@ class SvxBoxItem;
 
 class ScAttrIterator;
 class ScAttrArray;
+struct ScAttrEntry;
 class ScBaseCell;
 class ScDocument;
 class ScEditDataArray;
@@ -321,6 +322,7 @@ public:
     void		ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr );
     void		ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr,
                                   ScEditDataArray* pDataArray = NULL );
+    bool        SetAttrEntries(ScAttrEntry* pData, SCSIZE nSize);
     void		SetPattern( SCROW nRow, const ScPatternAttr& rPatAttr, BOOL bPutToPool = FALSE );
     void		SetPatternArea( SCROW nStartRow, SCROW nEndRow,
                                 const ScPatternAttr& rPatAttr, BOOL bPutToPool = FALSE );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 25c352a..c59576b 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -83,6 +83,7 @@ class Window;
 class XColorTable;
 class List;
 
+struct ScAttrEntry;
 class ScAutoFormatData;
 class ScBaseCell;
 class ScStringCell;
@@ -1211,6 +1212,9 @@ public:
     SC_DLLPUBLIC void			ApplyPatternAreaTab( SCCOL nStartCol, SCROW nStartRow,
                                             SCCOL nEndCol, SCROW nEndRow, SCTAB nTab,
                                             const ScPatternAttr& rAttr );
+
+    SC_DLLPUBLIC bool SetAttrEntries(SCCOL nCol, SCTAB nTab, ScAttrEntry* pData, SCSIZE nSize);
+
     SC_DLLPUBLIC void			ApplyPatternIfNumberformatIncompatible(
                             const ScRange& rRange, const ScMarkData& rMark,
                             const ScPatternAttr& rPattern, short nNewType );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 83697ef..0e37f1b 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -537,6 +537,8 @@ public:
     void		ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr );
     void		ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
                                   const ScPatternAttr& rAttr, ScEditDataArray* pDataArray = NULL );
+    bool        SetAttrEntries(SCCOL nCol, ScAttrEntry* pData, SCSIZE nSize);
+
     void		SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr, BOOL bPutToPool = FALSE )
                     {
                         if (ValidColRow(rPos.Col(),rPos.Row()))
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 8d0c530..36886ea 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -836,6 +836,21 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCac
 #endif
 }
 
+bool ScAttrArray::SetAttrEntries(ScAttrEntry* pNewData, SCSIZE nSize)
+{
+    if (pData)
+    {
+        ScDocumentPool* pDocPool = pDocument->GetPool();
+        for (SCSIZE i=0; i<nCount; i++)
+            pDocPool->Remove(*pData[i].pPattern);
+
+        delete[] pData;
+    }
+
+    pData = pNewData;
+    nCount = nLimit = nSize;
+    return true;
+}
 
 void lcl_MergeDeep( SfxItemSet& rMergeSet, const SfxItemSet& rSource )
 {
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index b29ab09..1623e48 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -475,6 +475,10 @@ void ScColumn::ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPattern
     pAttrArray->ApplyCacheArea( nStartRow, nEndRow, &aCache, pDataArray );
 }
 
+bool ScColumn::SetAttrEntries(ScAttrEntry* pData, SCSIZE nSize)
+{
+    return pAttrArray->SetAttrEntries(pData, nSize);
+}
 
 void ScColumn::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
         const ScPatternAttr& rPattern, short nNewType )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 82e1ab9..89d2d8f 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3909,6 +3909,14 @@ void ScDocument::ApplyPatternAreaTab( SCCOL nStartCol, SCROW nStartRow,
             pTab[nTab]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr );
 }
 
+bool ScDocument::SetAttrEntries(SCCOL nCol, SCTAB nTab, ScAttrEntry* pData, SCSIZE nSize)
+{
+    if (!ValidTab(nTab) || !pTab[nTab])
+        return false;
+
+    return pTab[nTab]->SetAttrEntries(nCol, pData, nSize);
+}
+
 void ScDocument::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
         const ScMarkData& rMark, const ScPatternAttr& rPattern, short nNewType )
 {
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index c53722a..d7068ce 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1855,6 +1855,14 @@ void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol,
     }
 }
 
+bool ScTable::SetAttrEntries(SCCOL nCol, ScAttrEntry* pData, SCSIZE nSize)
+{
+    if (!ValidCol(nCol))
+        return false;
+
+    return aCol[nCol].SetAttrEntries(pData, nSize);
+}
+
 void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
         const ScPatternAttr& rPattern, short nNewType )
 {
diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
index b1ce3a0..9fa8158 100644
--- a/sc/source/filter/excel/xistyle.cxx
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -58,12 +58,18 @@
 #include "stlsheet.hxx"
 #include "cell.hxx"
 #include "globstr.hrc"
+#include "attarray.hxx"
 #include "xltracer.hxx"
 #include "xistream.hxx"
 #include "xicontent.hxx"
 
 #include "root.hxx"
 #include "colrowst.hxx"
+#include "svl/poolcach.hxx"
+
+#include <list>
+
+using ::std::list;
 
 // PALETTE record - color information =========================================
 
@@ -1181,26 +1187,60 @@ const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs )
     return *mpPattern;
 }
 
-void XclImpXF::ApplyPattern(
-        SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2,
-        SCTAB nScTab, ULONG nForceScNumFmt )
+void XclImpXF::ApplyPatternToAttrList(
+    list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2, sal_uInt32 nForceScNumFmt)
 {
     // force creation of cell style and hard formatting, do it here to have mpStyleSheet
-    const ScPatternAttr& rPattern = CreatePattern();
+    const ScPatternAttr& rOrigPat = CreatePattern();
+    ScPatternAttr aNewPat = rOrigPat;
+    const ScPatternAttr* pPat = NULL;
 
     // insert into document
     ScDocument& rDoc = GetDoc();
-    if( IsCellXF() && mpStyleSheet )
-        rDoc.ApplyStyleAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, *mpStyleSheet );
-    if( HasUsedFlags() )
-        rDoc.ApplyPatternAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, rPattern );
 
-    // #108770# apply special number format
-    if( nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
+    if (IsCellXF() && mpStyleSheet)
+    {
+        // Style sheet exists.  Create a copy of the original pattern.
+        aNewPat.SetStyleSheet(mpStyleSheet);
+        pPat = &aNewPat;
+    }
+
+    if (HasUsedFlags())
+    {
+        if (!pPat)
+            pPat = &aNewPat;
+
+        SfxItemPoolCache aCache(rDoc.GetPool(), &rOrigPat.GetItemSet());
+        pPat = static_cast<const ScPatternAttr*>(&aCache.ApplyTo(*pPat, true));
+    }
+
+    if (nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND)
     {
-        ScPatternAttr aPattern( GetDoc().GetPool() );
-        GetNumFmtBuffer().FillScFmtToItemSet( aPattern.GetItemSet(), nForceScNumFmt );
-        rDoc.ApplyPatternAreaTab( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, aPattern );
+        if (!pPat)
+            pPat = &aNewPat;
+
+        ScPatternAttr aNumPat(GetDoc().GetPool());
+        GetNumFmtBuffer().FillScFmtToItemSet(aNumPat.GetItemSet(), nForceScNumFmt);
+        SfxItemPoolCache aCache(rDoc.GetPool(), &aNumPat.GetItemSet());
+        pPat = static_cast<const ScPatternAttr*>(&aCache.ApplyTo(*pPat, true));
+    }
+
+
+    if (pPat)
+    {
+        if (!rAttrs.empty() && rAttrs.back().nRow + 1 < nRow1)
+        {
+            // Fill this gap with the default pattern.
+            ScAttrEntry aEntry;
+            aEntry.nRow = nRow1 - 1;
+            aEntry.pPattern = rDoc.GetDefPattern();
+            rAttrs.push_back(aEntry);
+        }
+
+        ScAttrEntry aEntry;
+        aEntry.nRow = nRow2;
+        aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(*pPat));
+        rAttrs.push_back(aEntry);
     }
 }
 
@@ -1446,18 +1486,6 @@ ScStyleSheet* XclImpXFBuffer::CreateStyleSheet( sal_uInt16 nXFIndex )
     return (aIt == maStylesByXf.end()) ? 0 : aIt->second->CreateStyleSheet();
 }
 
-void XclImpXFBuffer::ApplyPattern(
-        SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2,
-        SCTAB nScTab, const XclImpXFIndex& rXFIndex )
-{
-    if( XclImpXF* pXF = GetXF( rXFIndex.GetXFIndex() ) )
-    {
-        // #108770# set 'Standard' number format for all Boolean cells
-        ULONG nForceScNumFmt = rXFIndex.IsBoolCell() ? GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND;
-        pXF->ApplyPattern( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, nForceScNumFmt );
-    }
-}
-
 // Buffer for XF indexes in cells =============================================
 
 IMPL_FIXEDMEMPOOL_NEWDEL( XclImpXFRange, 100, 500 )
@@ -1781,8 +1809,35 @@ void XclImpXFRangeBuffer::Finalize()
         {
             XclImpXFRangeColumn& rColumn = **aVIt;
             SCCOL nScCol = static_cast< SCCOL >( aVIt - aVBeg );
+            list<ScAttrEntry> aAttrs;
             for( XclImpXFRange* pStyle = rColumn.First(); pStyle; pStyle = rColumn.Next() )
-                rXFBuffer.ApplyPattern( nScCol, pStyle->mnScRow1, nScCol, pStyle->mnScRow2, nScTab, pStyle->maXFIndex );
+            {
+                const XclImpXFIndex& rXFIndex = pStyle->maXFIndex;
+                XclImpXF* pXF = rXFBuffer.GetXF( rXFIndex.GetXFIndex() );
+                if (!pXF)
+                    continue;
+
+                sal_uInt32 nForceScNumFmt = rXFIndex.IsBoolCell() ?
+                    GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND;
+
+                pXF->ApplyPatternToAttrList(aAttrs, pStyle->mnScRow1, pStyle->mnScRow2, nForceScNumFmt);
+            }
+
+            if (aAttrs.empty() || aAttrs.back().nRow != MAXROW)
+            {
+                ScAttrEntry aEntry;
+                aEntry.nRow = MAXROW;
+                aEntry.pPattern = rDoc.GetDefPattern();
+                aAttrs.push_back(aEntry);
+            }
+
+            size_t nAttrSize = aAttrs.size();
+            ScAttrEntry* pData = new ScAttrEntry[nAttrSize];
+            list<ScAttrEntry>::const_iterator itr = aAttrs.begin(), itrEnd = aAttrs.end();
+            for (size_t i = 0; itr != itrEnd; ++itr, ++i)
+                pData[i] = *itr;
+
+            rDoc.SetAttrEntries(nScCol, nScTab, pData, static_cast<SCSIZE>(nAttrSize));
         }
     }
 
diff --git a/sc/source/filter/inc/xistyle.hxx b/sc/source/filter/inc/xistyle.hxx
index 1d3047e..724af90 100644
--- a/sc/source/filter/inc/xistyle.hxx
+++ b/sc/source/filter/inc/xistyle.hxx
@@ -37,6 +37,7 @@
 #include "xiroot.hxx"
 
 class ScDocumentPool;
+class ScAttrEntry;
 
 /* ============================================================================
 - Buffers for style records (PALETTE, FONT, FORMAT, XF)
@@ -406,14 +407,9 @@ public:
         @return  A read-only reference to the item set stored internally. */
     const ScPatternAttr& CreatePattern( bool bSkipPoolDefs = false );
 
-    /** Inserts all formatting attributes to the specified area in the Calc document.
-        @param nForcedNumFmt  If not set to NUMBERFORMAT_ENTRY_NOT_FOUND, it will overwrite
-        the number format of the XF. */
-    void                ApplyPattern(
-                            SCCOL nScCol1, SCROW nScRow1,
-                            SCCOL nScCol2, SCROW nScRow2,
-                            SCTAB nScTab,
-                            ULONG nForceScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND );
+    void                ApplyPatternToAttrList(
+                            ::std::list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2,
+                            sal_uInt32 nForceScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND);
 
 private:
     void                ReadXF2( XclImpStream& rStrm );
@@ -509,14 +505,6 @@ public:
         @return  The pointer to the cell style sheet, or 0, if there is no style sheet. */
     ScStyleSheet*       CreateStyleSheet( sal_uInt16 nXFIndex );
 
-    /** Inserts formatting attributes from an XF to the specified area in the Calc document.
-        @param nForcedNumFmt  If not set to NUMBERFORMAT_ENTRY_NOT_FOUND, it will overwrite
-        the number format of the XF. */
-    void                ApplyPattern(
-                            SCCOL nScCol1, SCROW nScRow1,
-                            SCCOL nScCol2, SCROW nScRow2,
-                            SCTAB nScTab, const XclImpXFIndex& rXFIndex );
-
 private:
     typedef ScfDelList< XclImpStyle >               XclImpStyleList;
     typedef ::std::map< sal_uInt16, XclImpStyle* >  XclImpStyleMap;
commit 27cc87b983cfc95e59d3872c8e2e45d756cfd57d
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Oct 4 14:10:29 2010 -0400

    Ported calc-perf-ods-import-cellstyles.diff from ooo-build.
    
    This patch improves import performance of large ods files.

diff --git a/sc/inc/simplerangelist.hxx b/sc/inc/simplerangelist.hxx
new file mode 100644
index 0000000..4a0c257
--- /dev/null
+++ b/sc/inc/simplerangelist.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: rangelst.hxx,v $
+ * $Revision: 1.9.32.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __SC_SIMPLERANGELIST_HXX__
+#define __SC_SIMPLERANGELIST_HXX__
+
+#include <boost/shared_ptr.hpp>
+
+#include "address.hxx"
+
+#include <map>
+#include <list>
+
+class ScAddress;
+class ScRange;
+class ScRangeList;
+
+/**
+ * This container is optimized for use in the ods import filter, to store
+ * ranges for cell styles.  We may change the name of this class once we
+ * have a better name for what it does.  Using this is way more efficient
+ * than ScRangeList.
+ */
+class ScSimpleRangeList
+{
+public:
+    struct Range
+    {
+        SCCOL mnCol1;
+        SCROW mnRow1;
+        SCCOL mnCol2;
+        SCROW mnRow2;
+        explicit Range(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
+
+        bool contains(const Range& r) const;
+    };
+    typedef ::boost::shared_ptr< ::std::list<Range> > RangeListRef;
+    typedef ::std::map<SCTAB, RangeListRef> TabType;
+
+    ScSimpleRangeList();
+
+    void addRange(const ScRange& rRange);
+    void insertCol(SCCOL nCol, SCTAB nTab);
+    void insertRow(SCROW nRow, SCTAB nTab);
+    void getRangeList(::std::list<ScRange>& rList) const;
+    void clear();
+
+private:
+    RangeListRef findTab(SCTAB nTab);
+
+private:
+    TabType maTabs;
+};
+
+#endif
diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk
index 9c4cac2..9819cf2 100644
--- a/sc/source/core/tool/makefile.mk
+++ b/sc/source/core/tool/makefile.mk
@@ -104,6 +104,7 @@ SLOFILES =  \
         $(SLO)$/reftokenhelper.obj \
         $(SLO)$/refupdat.obj \
         $(SLO)$/scmatrix.obj \
+        $(SLO)$/simplerangelist.obj \
         $(SLO)$/stringutil.obj \
         $(SLO)$/subtotal.obj \
         $(SLO)$/token.obj \
@@ -133,6 +134,7 @@ EXCEPTIONSFILES= \
         $(SLO)$/prnsave.obj \
         $(SLO)$/queryparam.obj \
         $(SLO)$/reftokenhelper.obj \
+        $(SLO)$/simplerangelist.obj \
         $(SLO)$/stringutil.obj \
         $(SLO)$/token.obj
 
diff --git a/sc/source/core/tool/simplerangelist.cxx b/sc/source/core/tool/simplerangelist.cxx
new file mode 100644
index 0000000..ca86775
--- /dev/null
+++ b/sc/source/core/tool/simplerangelist.cxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: rangelst.hxx,v $
+ * $Revision: 1.9.32.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//------------------------------------------------------------------------
+
+#include "simplerangelist.hxx"
+#include "rangelst.hxx"
+
+using ::std::list;
+using ::std::pair;
+using ::std::max;
+
+// ============================================================================
+
+ScSimpleRangeList::Range::Range(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) :
+    mnCol1(nCol1), mnRow1(nRow1), mnCol2(nCol2), mnRow2(nRow2) {}
+
+bool ScSimpleRangeList::Range::contains(const Range& r) const
+{
+    return mnCol1 <= r.mnCol1 && mnRow1 <= r.mnRow1 && r.mnCol2 <= mnCol2 && r.mnRow2 <= mnRow2;
+}
+
+// ----------------------------------------------------------------------------
+
+ScSimpleRangeList::ScSimpleRangeList()
+{
+}
+
+namespace {
+
+bool maybeJoin(ScSimpleRangeList::Range& rOld, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
+{
+    if (rOld.mnRow1 == nRow1 && rOld.mnRow2 == nRow2)
+    {
+        // Check their column spans to see if they overlap.
+        if (rOld.mnCol1 == nCol1)
+        {
+            // Their share the start column position.
+            rOld.mnCol2 = max(rOld.mnCol2, nCol2);
+            return true;
+        }
+        else if (rOld.mnCol1 < nCol1)
+        {
+            // Old range sits on the left.
+            if (nCol1 - rOld.mnCol2 <= 1)
+            {
+                rOld.mnCol2 = max(rOld.mnCol2, nCol2);
+                return true;
+            }
+        }
+        else if (nCol1 < rOld.mnCol1)
+        {
+            // New range sits on the left.
+            if (nCol1 - rOld.mnCol2 <= 1)
+            {
+                rOld.mnCol1 = nCol1;
+                rOld.mnCol2 = max(rOld.mnCol2, nCol2);
+                return true;
+            }
+        }
+    }
+
+    if (rOld.mnCol1 == nCol1 && rOld.mnCol2 == nCol2)
+    {
+        if (rOld.mnRow1 == nRow1)
+        {
+            // Their share the start row position.
+            rOld.mnRow2 = max(rOld.mnRow2, nRow2);
+            return true;
+        }
+        else if (rOld.mnRow1 < nRow1)
+        {
+            // Old range sits above.
+            if (nRow1 - rOld.mnRow2 <= 1)
+            {
+                rOld.mnRow2 = max(rOld.mnRow2, nRow2);
+                return true;
+            }
+        }
+        else if (nRow1 < rOld.mnRow1)
+        {
+            // New range sits above.
+            if (nRow1 - rOld.mnRow2 <= 1)
+            {
+                rOld.mnRow1 = nRow1;
+                rOld.mnRow2 = max(rOld.mnRow2, nRow2);
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+}
+
+void ScSimpleRangeList::addRange(const ScRange& rRange)
+{
+    SCCOL nCol1 = rRange.aStart.Col();
+    SCROW nRow1 = rRange.aStart.Row();
+    SCTAB nTab1 = rRange.aStart.Tab();
+    SCCOL nCol2 = rRange.aEnd.Col();
+    SCROW nRow2 = rRange.aEnd.Row();
+    SCTAB nTab2 = rRange.aEnd.Tab();
+
+    for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
+    {
+        RangeListRef pRef = findTab(nTab);
+        if (!pRef)
+            // This should never happen!
+            return;
+
+        if (pRef->empty() || !maybeJoin(pRef->back(), nCol1, nRow1, nCol2, nRow2))
+            // Not joinable.  Append it to the list.
+            pRef->push_back(Range(nCol1, nRow1, nCol2, nRow2));
+    }
+}
+
+void ScSimpleRangeList::insertCol(SCCOL nCol, SCTAB nTab)
+{
+    RangeListRef pRef = findTab(nTab);
+    if (!pRef)
+        // This should never happen!
+        return;
+
+    list<Range>::iterator itr = pRef->begin(), itrEnd = pRef->end();
+    for (; itr != itrEnd; ++itr)
+    {
+        Range& r = *itr;
+        if (r.mnCol2 < nCol)
+            // insertion point to the right of the range.
+            continue;
+
+        if (nCol <= r.mnCol1)
+        {
+            // insertion point to the left of the range.
+            ++r.mnCol1;
+            ++r.mnCol2;
+        }
+        else if (nCol <= r.mnCol2)
+        {
+            // insertion point cuts through the range.
+            ++r.mnCol2;
+        }
+    }
+}
+
+void ScSimpleRangeList::insertRow(SCROW nRow, SCTAB nTab)
+{
+    RangeListRef pRef = findTab(nTab);
+    if (!pRef)
+        // This should never happen!
+        return;
+
+    list<Range>::iterator itr = pRef->begin(), itrEnd = pRef->end();
+    for (; itr != itrEnd; ++itr)
+    {
+        Range& r = *itr;
+        if (r.mnRow2 < nRow)
+            // insertion point is below the range.
+            continue;
+
+        if (nRow <= r.mnRow1)
+        {
+            // insertion point is above the range.
+            ++r.mnRow1;
+            ++r.mnRow2;
+        }
+        else if (nRow <= r.mnRow2)
+        {
+            // insertion point cuts through the range.
+            ++r.mnRow2;
+        }
+    }
+}
+
+void ScSimpleRangeList::getRangeList(list<ScRange>& rList) const
+{
+    list<ScRange> aList;
+    for (TabType::const_iterator itrTab = maTabs.begin(), itrTabEnd = maTabs.end(); itrTab != itrTabEnd; ++itrTab)
+    {
+        SCTAB nTab = itrTab->first;
+        const RangeListRef& pRanges = itrTab->second;
+        list<Range>::const_iterator itr = pRanges->begin(), itrEnd = pRanges->end();
+        for (; itr != itrEnd; ++itr)
+        {
+            const Range& r = *itr;
+            aList.push_back(ScRange(r.mnCol1, r.mnRow1, nTab, r.mnCol2, r.mnRow2, nTab));
+        }
+    }
+    rList.swap(aList);
+}
+
+void ScSimpleRangeList::clear()
+{
+    maTabs.clear();
+}
+
+ScSimpleRangeList::RangeListRef ScSimpleRangeList::findTab(SCTAB nTab)
+{
+    TabType::iterator itr = maTabs.find(nTab);
+    if (itr == maTabs.end())
+    {
+        RangeListRef p(new list<Range>);
+        pair<TabType::iterator, bool> r = maTabs.insert(TabType::value_type(nTab, p));
+        if (!r.second)
+            return RangeListRef();
+        itr = r.first;
+    }
+
+    return itr->second;
+}
diff --git a/sc/source/filter/xml/XMLStylesImportHelper.cxx b/sc/source/filter/xml/XMLStylesImportHelper.cxx
index 976d204..c54997b 100644
--- a/sc/source/filter/xml/XMLStylesImportHelper.cxx
+++ b/sc/source/filter/xml/XMLStylesImportHelper.cxx
@@ -37,6 +37,7 @@
 #include <com/sun/star/util/NumberFormat.hpp>
 
 using namespace com::sun::star;
+using ::std::list;
 
 void ScMyStyleNumberFormats::AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat)
 {
@@ -53,37 +54,14 @@ sal_Int32 ScMyStyleNumberFormats::GetStyleNumberFormat(const rtl::OUString& rSty
         return aItr->nNumberFormat;
 }
 
-ScMyStyleRanges::ScMyStyleRanges()
-    :
-    pTextList(NULL),
-    pNumberList(NULL),
-    pTimeList(NULL),
-    pDateTimeList(NULL),
-    pPercentList(NULL),
-    pLogicalList(NULL),
-    pUndefinedList(NULL),
+ScMyStyleRanges::ScMyStyleRanges() :
     pCurrencyList(NULL)
 {
 }
 
 ScMyStyleRanges::~ScMyStyleRanges()
 {
-    if (pTextList)
-        delete pTextList;
-    if (pNumberList)
-        delete pNumberList;
-    if (pTimeList)
-        delete pTimeList;
-    if (pDateTimeList)
-        delete pDateTimeList;
-    if (pPercentList)
-        delete pPercentList;
-    if (pLogicalList)
-        delete pLogicalList;
-    if (pUndefinedList)
-        delete pUndefinedList;
-    if (pCurrencyList)
-        delete pCurrencyList;
+    delete pCurrencyList;
 }
 
 void ScMyStyleRanges::AddRange(const ScRange& rRange, ScRangeList* pList,
@@ -135,58 +113,58 @@ void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange, ScRangeListRef xLi
 }
 
 void ScMyStyleRanges::AddRange(const ScRange& rRange,
-    const rtl::OUString* pStyleName, const sal_Int16 nType,
-    ScXMLImport& rImport, const sal_uInt32 nMaxRanges)
+    const rtl::OUString* /*pStyleName*/, const sal_Int16 nType,
+    ScXMLImport& /*rImport*/, const sal_uInt32 /*nMaxRanges*/)
 {
     switch (nType)
     {
         case util::NumberFormat::NUMBER:
         {
-            if (!pNumberList)
-                pNumberList = new ScRangeList();
-            AddRange(rRange, pNumberList, pStyleName, nType, rImport, nMaxRanges);
+            if (!mpNumberList)
+                mpNumberList.reset(new ScSimpleRangeList);
+            mpNumberList->addRange(rRange);
         }
         break;
         case util::NumberFormat::TEXT:
         {
-            if (!pTextList)
-                pTextList = new ScRangeList();
-            AddRange(rRange, pTextList, pStyleName, nType, rImport, nMaxRanges);
+            if (!mpTextList)
+                mpTextList.reset(new ScSimpleRangeList);
+            mpTextList->addRange(rRange);
         }
         break;
         case util::NumberFormat::TIME:
         {
-            if (!pTimeList)
-                pTimeList = new ScRangeList();
-            AddRange(rRange, pTimeList, pStyleName, nType, rImport, nMaxRanges);
+            if (!mpTimeList)
+                mpTimeList.reset(new ScSimpleRangeList);
+            mpTimeList->addRange(rRange);
         }
         break;
         case util::NumberFormat::DATETIME:
         {
-            if (!pDateTimeList)
-                pDateTimeList = new ScRangeList();
-            AddRange(rRange, pDateTimeList, pStyleName, nType, rImport, nMaxRanges);
+            if (!mpDateTimeList)
+                mpDateTimeList.reset(new ScSimpleRangeList);
+            mpDateTimeList->addRange(rRange);
         }
         break;
         case util::NumberFormat::PERCENT:
         {
-            if (!pPercentList)
-                pPercentList = new ScRangeList();
-            AddRange(rRange, pPercentList, pStyleName, nType, rImport, nMaxRanges);
+            if (!mpPercentList)
+                mpPercentList.reset(new ScSimpleRangeList);
+            mpPercentList->addRange(rRange);
         }
         break;
         case util::NumberFormat::LOGICAL:
         {
-            if (!pLogicalList)
-                pLogicalList = new ScRangeList();
-            AddRange(rRange, pLogicalList, pStyleName, nType, rImport, nMaxRanges);
+            if (!mpLogicalList)
+                mpLogicalList.reset(new ScSimpleRangeList);
+            mpLogicalList->addRange(rRange);
         }
         break;
         case util::NumberFormat::UNDEFINED:
         {
-            if (!pUndefinedList)
-                pUndefinedList = new ScRangeList();
-            AddRange(rRange, pUndefinedList, pStyleName, nType, rImport, nMaxRanges);
+            if (!mpUndefinedList)
+                mpUndefinedList.reset(new ScSimpleRangeList);
+            mpUndefinedList->addRange(rRange);
         }
         break;
         default:
@@ -213,53 +191,78 @@ void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange,
         if (aPair.second)
         {
             aItr = aPair.first;
-            AddCurrencyRange(rRange, aItr->xRanges, pStyleName, pCurrency, rImport, nMaxRanges);
+            aItr->mpRanges->addRange(rRange);
         }
     }
     else
-        aItr->xRanges->Join(rRange);
+        aItr->mpRanges->addRange(rRange);
 }
 
-void ScMyStyleRanges::InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy,
-        const SCsTAB nDz, ScDocument* pDoc)
+void ScMyStyleRanges::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc)
 {
-    UpdateRefMode aRefMode(URM_INSDEL);
-    if (pNumberList)
-        pNumberList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
-    if (pTextList)
-        pTextList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
-    if (pTimeList)
-        pTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
-    if (pDateTimeList)
-        pDateTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
-    if (pPercentList)
-        pPercentList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
-    if (pLogicalList)
-        pLogicalList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
-    if (pUndefinedList)
-        pUndefinedList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+    if (mpTextList)
+        mpTextList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+    if (mpNumberList)
+        mpNumberList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+    if (mpTimeList)
+        mpTimeList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+    if (mpDateTimeList)
+        mpDateTimeList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+    if (mpPercentList)
+        mpPercentList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+    if (mpLogicalList)
+        mpLogicalList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+    if (mpUndefinedList)
+        mpUndefinedList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+
     if (pCurrencyList)
     {
         ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
         ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
         while (aItr != aEndItr)
         {
-            aItr->xRanges->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+            aItr->mpRanges->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
             ++aItr;
         }
     }
 }
 
-void ScMyStyleRanges::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc)
+void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc)
 {
-    InsertColRow(ScRange(0, static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab),
-        MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 0, 1, 0, pDoc);
+    if (mpTextList)
+        mpTextList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+    if (mpNumberList)
+        mpNumberList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+    if (mpTimeList)
+        mpTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+    if (mpDateTimeList)
+        mpDateTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+    if (mpPercentList)
+        mpPercentList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+    if (mpLogicalList)
+        mpLogicalList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+    if (mpUndefinedList)
+        mpUndefinedList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+
+    if (pCurrencyList)
+    {
+        ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+        ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+        while (aItr != aEndItr)
+        {
+            aItr->mpRanges->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+            ++aItr;
+        }
+    }
 }
 
-void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc)
+void ScMyStyleRanges::SetStylesToRanges(const list<ScRange>& rRanges,
+    const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+    const rtl::OUString* pCurrency, ScXMLImport& rImport)
 {
-    InsertColRow(ScRange(static_cast<SCCOL>(nCol), 0, static_cast<SCTAB>(nTab),
-        MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 1, 0, 0, pDoc);
+    list<ScRange>::const_iterator itr = rRanges.begin(), itrEnd = rRanges.end();
+    for (; itr != itrEnd; ++itr)
+        rImport.SetStyleToRange(*itr, pStyleName, nCellType, pCurrency);
 }
 
 void ScMyStyleRanges::SetStylesToRanges(ScRangeList* pList,
@@ -282,27 +285,64 @@ void ScMyStyleRanges::SetStylesToRanges(ScRangeListRef xList,
 
 void ScMyStyleRanges::SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport)
 {
-    if (pNumberList)
-        SetStylesToRanges(pNumberList, pStyleName, util::NumberFormat::NUMBER, NULL, rImport);
-    if (pTextList)
-        SetStylesToRanges(pTextList, pStyleName, util::NumberFormat::TEXT, NULL, rImport);
-    if (pTimeList)
-        SetStylesToRanges(pTimeList, pStyleName, util::NumberFormat::TIME, NULL, rImport);
-    if (pDateTimeList)
-        SetStylesToRanges(pDateTimeList, pStyleName, util::NumberFormat::DATETIME, NULL, rImport);
-    if (pPercentList)
-        SetStylesToRanges(pPercentList, pStyleName, util::NumberFormat::PERCENT, NULL, rImport);
-    if (pLogicalList)
-        SetStylesToRanges(pLogicalList, pStyleName, util::NumberFormat::LOGICAL, NULL, rImport);
-    if (pUndefinedList)
-        SetStylesToRanges(pUndefinedList, pStyleName, util::NumberFormat::UNDEFINED, NULL, rImport);
+    if (mpNumberList)
+    {
+        list<ScRange> aList;
+        mpNumberList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::NUMBER, NULL, rImport);
+        mpNumberList->clear();
+    }
+    if (mpTextList)
+    {
+        list<ScRange> aList;
+        mpTextList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::TEXT, NULL, rImport);
+        mpTextList->clear();
+    }
+    if (mpTimeList)
+    {
+        list<ScRange> aList;
+        mpTimeList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::TIME, NULL, rImport);
+        mpTimeList->clear();
+    }
+    if (mpDateTimeList)
+    {
+        list<ScRange> aList;
+        mpDateTimeList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::DATETIME, NULL, rImport);
+        mpDateTimeList->clear();
+    }
+    if (mpPercentList)
+    {
+        list<ScRange> aList;
+        mpPercentList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::PERCENT, NULL, rImport);
+        mpPercentList->clear();
+    }
+    if (mpLogicalList)
+    {
+        list<ScRange> aList;
+        mpLogicalList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::LOGICAL, NULL, rImport);
+        mpLogicalList->clear();
+    }
+    if (mpUndefinedList)
+    {
+        list<ScRange> aList;
+        mpUndefinedList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::UNDEFINED, NULL, rImport);
+        mpUndefinedList->clear();
+    }
     if (pCurrencyList)
     {
         ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
         ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
         while (aItr != aEndItr)
         {
-            SetStylesToRanges(aItr->xRanges, pStyleName, util::NumberFormat::CURRENCY, &aItr->sCurrency, rImport);
+            list<ScRange> aList;
+            aItr->mpRanges->getRangeList(aList);
+            SetStylesToRanges(aList, pStyleName, util::NumberFormat::CURRENCY, &aItr->sCurrency, rImport);
             ++aItr;
         }
     }
diff --git a/sc/source/filter/xml/XMLStylesImportHelper.hxx b/sc/source/filter/xml/XMLStylesImportHelper.hxx
index a0c2026..6e321f6 100644
--- a/sc/source/filter/xml/XMLStylesImportHelper.hxx
+++ b/sc/source/filter/xml/XMLStylesImportHelper.hxx
@@ -29,12 +29,15 @@
 #define SC_XMLSTYLESIMPORTHELPER_HXX
 
 #include "rangelst.hxx"
+#include "simplerangelist.hxx"
 #include <rtl/ustring.hxx>
 #include <com/sun/star/table/CellRangeAddress.hpp>
 #include <com/sun/star/table/CellAddress.hpp>
 
 #include <set>
 #include <vector>
+#include <list>
+#include <boost/shared_ptr.hpp>
 
 class ScXMLImport;
 
@@ -72,9 +75,11 @@ public:
 struct ScMyCurrencyStyle
 {
     rtl::OUString		sCurrency;
-    ScRangeListRef		xRanges;
+    ::boost::shared_ptr<ScSimpleRangeList> mpRanges;
 
-    ScMyCurrencyStyle() : xRanges(new ScRangeList()) {}
+    ScMyCurrencyStyle() :
+        mpRanges(new ScSimpleRangeList)
+    {}
     ~ScMyCurrencyStyle() {}
 };
 
@@ -90,13 +95,13 @@ typedef std::set<ScMyCurrencyStyle, LessCurrencyStyle>	ScMyCurrencyStylesSet;
 
 class ScMyStyleRanges : public SvRefBase
 {
-    ScRangeList*			pTextList;
-    ScRangeList*			pNumberList;
-    ScRangeList*			pTimeList;
-    ScRangeList*			pDateTimeList;
-    ScRangeList*			pPercentList;
-    ScRangeList*			pLogicalList;
-    ScRangeList*			pUndefinedList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpTextList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpNumberList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpTimeList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpDateTimeList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpPercentList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpLogicalList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpUndefinedList;
     ScMyCurrencyStylesSet*	pCurrencyList;
 
     void AddRange(const ScRange& rRange, ScRangeList* pList,
@@ -105,8 +110,9 @@ class ScMyStyleRanges : public SvRefBase
     void AddCurrencyRange(const ScRange& rRange, ScRangeListRef xList,
         const rtl::OUString* pStyleName, const rtl::OUString* pCurrency,
         ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
-    void InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy,
-        const SCsTAB nDz, ScDocument* pDoc);
+    void SetStylesToRanges(const ::std::list<ScRange>& rList,
+        const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+        const rtl::OUString* pCurrency, ScXMLImport& rImport);
     void SetStylesToRanges(ScRangeList* pList,
         const rtl::OUString* pStyleName, const sal_Int16 nCellType,
         const rtl::OUString* pCurrency, ScXMLImport& rImport);


More information about the ooo-build-commit mailing list