[ooo-build-commit] patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Dec 8 18:42:59 PST 2009


 patches/dev300/apply                                  |    6 
 patches/dev300/calc-perf-import-dbf-connectivity.diff |  103 +
 patches/dev300/calc-perf-import-dbf-sc.diff           |  966 ++++++++++++++++++
 3 files changed, 1075 insertions(+)

New commits:
commit c3c976fa727fd1f60bd9cd7f8d46e2571f73757d
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Tue Dec 8 21:04:18 2009 -0500

    Improve import performance of DBF files by 75%.
    
    * patches/dev300/apply: add the following patches, to fix n#558505.
    
    * patches/dev300/calc-perf-import-dbf-connectivity.diff: avoid unnecessarily
      calling EraseLeadingChars() and EraseTrailingChars() which results in the
      string buffer being scanned multiple times.  This improves the import
      performance on large DBF files.
    
    * patches/dev300/calc-perf-import-dbf-sc.diff: Use double-buffering on
      column cell allocations, and avoid unnecessarily column row size
      adjustments.

diff --git a/patches/dev300/apply b/patches/dev300/apply
index d0bc6fd..9ac4e76 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3500,3 +3500,9 @@ speed-sfx2-dont-throw-too-much.diff, i#107512, jholesov
 svtools-emf-fix.diff, i#105480, rodo
 svtools-wmf-clean-warnings.diff, rodo
 svtools-embedemf.diff, i#107291, rodo
+
+[ CalcRowLimit ]
+
+# Improve import performance of dbf files by ~75%.
+calc-perf-import-dbf-connectivity.diff, n#558505, kohei
+calc-perf-import-dbf-sc.diff,           n#558505, kohei
diff --git a/patches/dev300/calc-perf-import-dbf-connectivity.diff b/patches/dev300/calc-perf-import-dbf-connectivity.diff
new file mode 100644
index 0000000..383953f
--- /dev/null
+++ b/patches/dev300/calc-perf-import-dbf-connectivity.diff
@@ -0,0 +1,103 @@
+diff --git connectivity/source/drivers/dbase/DTable.cxx connectivity/source/drivers/dbase/DTable.cxx
+index 216dc2d..f642b6f 100644
+--- connectivity/source/drivers/dbase/DTable.cxx
++++ connectivity/source/drivers/dbase/DTable.cxx
+@@ -887,17 +887,23 @@ sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, s
+ 
+         if (nType == DataType::CHAR || nType == DataType::VARCHAR)
+         {
+-            char cLast = pData[nLen];
+-            pData[nLen] = 0;
+-            String aStr(pData,(xub_StrLen)nLen,m_eEncoding);
+-            aStr.EraseTrailingChars();
+-
+-            if ( aStr.Len() )
+-                *(_rRow->get())[i] = ::rtl::OUString(aStr);
+-            else// keine StringLaenge, dann NULL
++            sal_Int32 nLastPos = -1;
++            for (sal_Int32 k = 0; k < nLen; ++k)
++            {
++                if (pData[k] != ' ')
++                    // Record last non-empty position.
++                    nLastPos = k;
++            }
++            if (nLastPos < 0)
++            {
++                // Empty string.  Skip it.
+                 (_rRow->get())[i]->setNull();
+-                
+-            pData[nLen] = cLast;
++            }
++            else
++            {
++                // Commit the string.  Use intern() to ref-count it.
++                *(_rRow->get())[i] = ::rtl::OUString::intern(pData, static_cast<sal_Int32>(nLastPos+1), m_eEncoding);
++            }                
+         } // if (nType == DataType::CHAR || nType == DataType::VARCHAR)
+         else if ( DataType::TIMESTAMP == nType )
+         {
+@@ -943,36 +949,46 @@ sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, s
+         }
+         else
+         {
++            sal_Int32 nPos1 = -1, nPos2 = -1;
+             // Falls Nul-Zeichen im String enthalten sind, in Blanks umwandeln!
+             for (sal_Int32 k = 0; k < nLen; k++)
+             {
+                 if (pData[k] == '\0')
+                     pData[k] = ' ';
+-            }
+ 
+-            String aStr(pData, (xub_StrLen)nLen,m_eEncoding);		// Spaces am Anfang und am Ende entfernen:
+-            aStr.EraseLeadingChars();
+-            aStr.EraseTrailingChars();
++                if (pData[k] != ' ')
++                {
++                    if (nPos1 < 0)
++                        // first non-empty char position.
++                        nPos1 = k;
++
++                    // last non-empty char position.
++                    nPos2 = k;
++                }
++            }
+ 
+-            if (!aStr.Len())
++            if (nPos1 < 0)
+             {
++                // Empty string.  Skip it.
+                 nByteOffset += nLen;
+                 (_rRow->get())[i]->setNull();	// keine Werte -> fertig
+                 continue;
+             }
+ 
++            ::rtl::OUString aStr = ::rtl::OUString::intern(pData+nPos1, nPos2-nPos1+1, m_eEncoding);
++
+             switch (nType)
+             {
+                 case DataType::DATE:
+                 {
+-                    if (aStr.Len() != nLen)
++                    if (aStr.getLength() != nLen)
+                     {
+                         (_rRow->get())[i]->setNull();
+                         break;
+                     }
+-                    const sal_uInt16  nYear   = (sal_uInt16)aStr.Copy( 0, 4 ).ToInt32();
+-                    const sal_uInt16  nMonth  = (sal_uInt16)aStr.Copy( 4, 2 ).ToInt32();
+-                    const sal_uInt16  nDay    = (sal_uInt16)aStr.Copy( 6, 2 ).ToInt32();
++                    const sal_uInt16  nYear   = (sal_uInt16)aStr.copy( 0, 4 ).toInt32();
++                    const sal_uInt16  nMonth  = (sal_uInt16)aStr.copy( 4, 2 ).toInt32();
++                    const sal_uInt16  nDay    = (sal_uInt16)aStr.copy( 6, 2 ).toInt32();
+ 
+                     const ::com::sun::star::util::Date aDate(nDay,nMonth,nYear);
+                     *(_rRow->get())[i] = aDate;
+@@ -1000,7 +1016,7 @@ sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, s
+                 case DataType::BINARY:
+                 case DataType::LONGVARCHAR:
+                 {
+-                    const long nBlockNo = aStr.ToInt32();	// Blocknummer lesen
++                    const long nBlockNo = aStr.toInt32();	// Blocknummer lesen
+                     if (nBlockNo > 0 && m_pMemoStream) // Daten aus Memo-Datei lesen, nur wenn
+                     {
+                         if ( !ReadMemo(nBlockNo, (_rRow->get())[i]->get()) )
diff --git a/patches/dev300/calc-perf-import-dbf-sc.diff b/patches/dev300/calc-perf-import-dbf-sc.diff
new file mode 100644
index 0000000..c8b51b2
--- /dev/null
+++ b/patches/dev300/calc-perf-import-dbf-sc.diff
@@ -0,0 +1,966 @@
+diff --git sc/inc/column.hxx sc/inc/column.hxx
+index 1d3cad9..a664cfd 100644
+--- sc/inc/column.hxx
++++ sc/inc/column.hxx
+@@ -71,6 +71,7 @@ struct ScLineFlags;
+ struct ScMergePatternState;
+ struct ScSetStringParam;
+ class ScFlatBoolRowSegments;
++struct ScColWidthParam;
+ 
+ #define COLUMN_DELTA	4
+ 
+@@ -125,8 +126,16 @@ friend class ScHorizontalCellIterator;
+ friend class ScHorizontalAttrIterator;
+ 
+ public:
+-static BOOL bDoubleAlloc;			// fuer Import: Groesse beim Allozieren verdoppeln
++    static bool bDoubleAlloc;			// fuer Import: Groesse beim Allozieren verdoppeln
+ 
++    class DoubleAllocSwitch
++    {
++    public:
++        DoubleAllocSwitch(bool bNewVal = true);
++        ~DoubleAllocSwitch();
++    private:
++        bool mbOldVal;
++    };
+ public:
+                 ScColumn();
+                 ~ScColumn();
+@@ -365,7 +374,7 @@ public:
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bFormula, USHORT nOldWidth,
+                                     const ScMarkData* pMarkData,
+-                                    BOOL bSimpleTextImport );
++                                    const ScColWidthParam* pParam );
+     void		GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT* pHeight,
+                                     OutputDevice* pDev,
+                                     double nPPTX, double nPPTY,
+diff --git sc/inc/dbdocutl.hxx sc/inc/dbdocutl.hxx
+index 52d2680..d3cddf7 100644
+--- sc/inc/dbdocutl.hxx
++++ sc/inc/dbdocutl.hxx
+@@ -45,10 +45,20 @@ namespace com { namespace sun { namespace star { namespace sdbc {
+ class ScDatabaseDocUtil
+ {
+ public:
++    /** 
++     * Detailed information on single string value.
++     */
++    struct StrData
++    {
++        bool        mbSimpleText;
++        sal_uInt32  mnStrLength;
++
++        StrData();
++    };
+     static void PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+                         const ::com::sun::star::uno::Reference<
+                             ::com::sun::star::sdbc::XRow>& xRow, long nRowPos,
+-                        long nType, BOOL bCurrency, BOOL* pSimpleFlag = NULL );
++                        long nType, BOOL bCurrency, StrData* pStrData = NULL );
+ };
+ 
+ #endif
+diff --git sc/inc/dociter.hxx sc/inc/dociter.hxx
+index 350c611..22cc806 100644
+--- sc/inc/dociter.hxx
++++ sc/inc/dociter.hxx
+@@ -38,6 +38,8 @@
+ #include "queryparam.hxx"
+ 
+ #include <memory>
++#include <vector>
++#include <boost/shared_ptr.hpp>
+ 
+ class ScDocument;
+ class ScBaseCell;
+@@ -45,6 +47,7 @@ class ScPatternAttr;
+ class ScAttrArray;
+ class ScAttrIterator;
+ class ScRange;
++class ScFlatBoolRowSegments;
+ 
+ class ScDocumentIterator				// alle nichtleeren Zellen durchgehen
+ {
+@@ -511,6 +514,42 @@ public:
+     const ScBaseCell*		GetCell() const			{ return pFoundCell; }
+ };
+ 
++// ============================================================================
++
++class ScDocRowHeightUpdater
++{
++public:
++    struct TabRanges
++    {
++        SCTAB mnTab;
++        ::boost::shared_ptr<ScFlatBoolRowSegments> mpRanges;
++
++        TabRanges();
++        TabRanges(SCTAB nTab);
++    };
++
++    /** 
++     * Passing a NULL pointer to pTabRangesArray forces the heights of all 
++     * rows in all tables to be updated. 
++     */
++    explicit ScDocRowHeightUpdater(
++        ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, 
++        const ::std::vector<TabRanges>* pTabRangesArray = NULL);
++
++    void update();
++
++private:
++    void updateAll();
++
++private:
++    ScDocument& mrDoc;
++    OutputDevice* mpOutDev;
++    double mfPPTX;
++    double mfPPTY;
++    const ::std::vector<TabRanges>* mpTabRangesArray;
++};
++
++
+ #endif
+ 
+ 
+diff --git sc/inc/docparam.hxx sc/inc/docparam.hxx
+new file mode 100644
+index 0000000..e273c01
+--- /dev/null
++++ sc/inc/docparam.hxx
+@@ -0,0 +1,47 @@
++/*************************************************************************
++ *
++ * 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: document.hxx,v $
++ * $Revision: 1.115.36.9 $
++ *
++ * 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_DOCPARAM_HXX
++#define SC_DOCPARAM_HXX
++
++#include "address.hxx"
++
++// Let's put here misc structures that get passed to ScDocument's methods.
++
++struct ScColWidthParam
++{
++    SCROW       mnMaxTextRow;
++    sal_uInt32  mnMaxTextLen;
++    bool        mbSimpleText;
++
++    ScColWidthParam();
++};
++
++#endif
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index 61e23c9..4d94701 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -141,6 +141,8 @@ class ScFormulaParserPool;
+ struct ScClipParam;        
+ struct ScClipRangeNameData;
+ struct ScSetStringParam;
++class ScDocRowHeightUpdater;
++struct ScColWidthParam;
+ 
+ namespace com { namespace sun { namespace star {
+     namespace lang {
+@@ -244,6 +246,7 @@ friend class ScHorizontalAttrIterator;
+ friend class ScDocAttrIterator;
+ friend class ScAttrRectIterator;
+ friend class ScDocShell;
++friend class ScDocRowHeightUpdater;
+ 
+ private:
+     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager;
+@@ -1276,7 +1279,7 @@ public:
+                                         const Fraction& rZoomX, const Fraction& rZoomY,
+                                         BOOL bFormula,
+                                         const ScMarkData* pMarkData = NULL,
+-                                        BOOL bSimpleTextImport = FALSE );
++                                        const ScColWidthParam* pParam = NULL );
+     SC_DLLPUBLIC BOOL			SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nExtra,
+                                         OutputDevice* pDev,
+                                         double nPPTX, double nPPTY,
+diff --git sc/inc/segmenttree.hxx sc/inc/segmenttree.hxx
+index 9b9d753..3199f7d 100644
+--- sc/inc/segmenttree.hxx
++++ sc/inc/segmenttree.hxx
+@@ -63,6 +63,16 @@ public:
+         bool    mbCurValue;
+     };
+ 
++    class RangeIterator
++    {
++    public:
++        explicit RangeIterator(ScFlatBoolRowSegments& rSegs);
++        bool getFirst(RangeData& rRange);
++        bool getNext(RangeData& rRange);
++    private:
++        ScFlatBoolRowSegments& mrSegs;
++    };
++
+     ScFlatBoolRowSegments();
+     ~ScFlatBoolRowSegments();
+ 
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index f0b39b3..9606b98 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -88,6 +88,7 @@ struct ScSetStringParam;
+ class ScFlatUInt16RowSegments;
+ class ScFlatBoolRowSegments;
+ class ScFlatBoolColSegments;
++struct ScColWidthParam;
+ 
+ typedef std::hash_map< ::rtl::OUString, rtl::OUString, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > NameToNameMap;
+ 
+@@ -592,7 +593,7 @@ public:
+                                     double nPPTX, double nPPTY,
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bFormula, const ScMarkData* pMarkData,
+-                                    BOOL bSimpleTextImport );
++                                    const ScColWidthParam* pParam );
+     BOOL		SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT nExtra,
+                                     OutputDevice* pDev,
+                                     double nPPTX, double nPPTY,
+diff --git sc/source/core/data/column.cxx sc/source/core/data/column.cxx
+index 98e470a..6da47f4 100644
+--- sc/source/core/data/column.cxx
++++ sc/source/core/data/column.cxx
+@@ -70,8 +70,20 @@ inline BOOL IsAmbiguousScriptNonZero( BYTE nScript )
+              nScript != 0 );
+ }
+ 
+-// -----------------------------------------------------------------------------------------
++// ----------------------------------------------------------------------------
+ 
++ScColumn::DoubleAllocSwitch::DoubleAllocSwitch(bool bNewVal) :
++    mbOldVal(ScColumn::bDoubleAlloc)
++{
++    ScColumn::bDoubleAlloc = bNewVal;
++}
++
++ScColumn::DoubleAllocSwitch::~DoubleAllocSwitch()
++{
++    ScColumn::bDoubleAlloc = mbOldVal;
++}
++
++// ----------------------------------------------------------------------------
+ 
+ ScColumn::ScColumn() :
+     nCol( 0 ),
+diff --git sc/source/core/data/column2.cxx sc/source/core/data/column2.cxx
+index c97fbda..10a3dd5 100644
+--- sc/source/core/data/column2.cxx
++++ sc/source/core/data/column2.cxx
+@@ -70,6 +70,7 @@
+ #include "dbcolect.hxx"
+ #include "fillinfo.hxx"
+ #include "segmenttree.hxx"
++#include "docparam.hxx"
+ 
+ #include <math.h>
+ 
+@@ -637,10 +638,10 @@ long ScColumn::GetSimpleTextNeededSize( SCSIZE nIndex, OutputDevice* pDev,
+ }
+ 
+ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nPPTY,
+-                                        const Fraction& rZoomX, const Fraction& rZoomY,
+-                                        BOOL bFormula, USHORT nOldWidth,
+-                                        const ScMarkData* pMarkData,
+-                                        BOOL bSimpleTextImport )
++                                     const Fraction& rZoomX, const Fraction& rZoomY,
++                                     BOOL bFormula, USHORT nOldWidth,
++                                     const ScMarkData* pMarkData,
++                                     const ScColWidthParam* pParam )
+ {
+     if (nCount == 0)
+         return nOldWidth;
+@@ -650,7 +651,7 @@ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nP
+ 
+     SCSIZE nIndex;
+     ScMarkedDataIter aDataIter(this, pMarkData, TRUE);
+-    if ( bSimpleTextImport )
++    if ( pParam && pParam->mbSimpleText )
+     {	// alles eins bis auf NumberFormate
+         const ScPatternAttr* pPattern = GetPattern( 0 );
+         Font aFont;
+@@ -661,19 +662,44 @@ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nP
+         long nMargin = (long) ( pMargin->GetLeftMargin() * nPPTX ) +
+                         (long) ( pMargin->GetRightMargin() * nPPTX );
+ 
+-        while (aDataIter.Next( nIndex ))
++        // Try to find the row that has the longest string, and measure the width of that string.
++        SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
++        ULONG nFormat = pPattern->GetNumberFormat( pFormatter );
++        String aLongStr;
++        Color* pColor;
++        if (pParam->mnMaxTextRow >= 0)
+         {
+-            USHORT nThis = (USHORT) (GetSimpleTextNeededSize( nIndex, pDev,
+-                TRUE ) + nMargin);
+-            if (nThis)
++            ScBaseCell* pCell = GetCell(pParam->mnMaxTextRow);
++            ScCellFormat::GetString(
++                pCell, nFormat, aLongStr, &pColor, *pFormatter, TRUE, FALSE, ftCheck );
++        }
++        else
++        {
++            xub_StrLen nLongLen = 0;
++            while (aDataIter.Next(nIndex))
+             {
+-                if (nThis>nWidth || !bFound)
++                if (nIndex >= nCount)
++                    // Out-of-bound reached.  No need to keep going.
++                    break;
++    
++                ScBaseCell* pCell = pItems[nIndex].pCell;
++                String aValStr;
++                ScCellFormat::GetString(
++                    pCell, nFormat, aValStr, &pColor, *pFormatter, TRUE, FALSE, ftCheck );
++                
++                if (aValStr.Len() > nLongLen)
+                 {
+-                    nWidth = nThis;
+-                    bFound = TRUE;
++                    nLongLen = aValStr.Len();
++                    aLongStr = aValStr;
+                 }
+             }
+         }
++
++        if (aLongStr.Len())
++        {    
++            nWidth = pDev->GetTextWidth(aLongStr) + static_cast<USHORT>(nMargin);
++            bFound = true;
++        }
+     }
+     else
+     {
+diff --git sc/source/core/data/column3.cxx sc/source/core/data/column3.cxx
+index b4e62a0..3982b9a 100644
+--- sc/source/core/data/column3.cxx
++++ sc/source/core/data/column3.cxx
+@@ -68,7 +68,7 @@ extern const ScFormulaCell* pLastFormulaTreeTop;	// in cellform.cxx
+ using namespace formula;
+ // STATIC DATA -----------------------------------------------------------
+ 
+-BOOL ScColumn::bDoubleAlloc = FALSE;	// fuer Import: Groesse beim Allozieren verdoppeln
++bool ScColumn::bDoubleAlloc = FALSE;    // fuer Import: Groesse beim Allozieren verdoppeln
+ 
+ 
+ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
+diff --git sc/source/core/data/dbdocutl.cxx sc/source/core/data/dbdocutl.cxx
+index 707f0da..a1146ad 100644
+--- sc/source/core/data/dbdocutl.cxx
++++ sc/source/core/data/dbdocutl.cxx
+@@ -49,12 +49,19 @@ using namespace ::com::sun::star;
+ 
+ #define D_TIMEFACTOR              86400.0
+ 
+-// -----------------------------------------------------------------------
++// ----------------------------------------------------------------------------
++
++ScDatabaseDocUtil::StrData::StrData() :
++    mbSimpleText(true), mnStrLength(0)
++{
++}
++
++// ----------------------------------------------------------------------------
+ 
+ // static
+ void ScDatabaseDocUtil::PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+                                 const uno::Reference<sdbc::XRow>& xRow, long nRowPos,
+-                                long nType, BOOL bCurrency, BOOL* pSimpleFlag )
++                                long nType, BOOL bCurrency, StrData* pStrData )
+ {
+     String aString;
+     double nVal = 0.0;
+@@ -188,8 +195,11 @@ void ScDatabaseDocUtil::PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB
+         if (aString.Len())
+         {
+             pCell = ScBaseCell::CreateTextCell( aString, pDoc );
+-            if ( pSimpleFlag && pCell->GetCellType() == CELLTYPE_EDIT )
+-                *pSimpleFlag = FALSE;
++            if (pStrData)
++            {    
++                pStrData->mbSimpleText = pCell->GetCellType() != CELLTYPE_EDIT;
++                pStrData->mnStrLength = aString.Len();
++            }
+         }
+         else
+             pCell = NULL;
+diff --git sc/source/core/data/dociter.cxx sc/source/core/data/dociter.cxx
+index 9f9dedb..d92187e 100644
+--- sc/source/core/data/dociter.cxx
++++ sc/source/core/data/dociter.cxx
+@@ -46,6 +46,10 @@
+ #include "patattr.hxx"
+ #include "docoptio.hxx"
+ #include "cellform.hxx"
++#include "segmenttree.hxx"
++#include "progress.hxx"
++#include "globstr.hrc"
++#include "tools/fract.hxx"
+ 
+ #include <vector>
+ 
+@@ -2110,3 +2114,96 @@ const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2,
+     return NULL;		// is nix mehr
+ }
+ 
++// ============================================================================
++
++ScDocRowHeightUpdater::TabRanges::TabRanges() :
++    mnTab(0), mpRanges(new ScFlatBoolRowSegments)
++{
++}
++
++ScDocRowHeightUpdater::TabRanges::TabRanges(SCTAB nTab) :
++    mnTab(nTab), mpRanges(new ScFlatBoolRowSegments)
++{
++}
++
++ScDocRowHeightUpdater::ScDocRowHeightUpdater(ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, const vector<TabRanges>* pTabRangesArray) :
++    mrDoc(rDoc), mpOutDev(pOutDev), mfPPTX(fPPTX), mfPPTY(fPPTY), mpTabRangesArray(pTabRangesArray)
++{
++}
++
++void ScDocRowHeightUpdater::update()
++{
++    if (!mpTabRangesArray || mpTabRangesArray->empty())
++    {
++        // No ranges defined.  Update all rows in all tables.
++        updateAll();
++        return;
++    }
++
++    sal_uInt32 nCellCount = 0;
++    vector<TabRanges>::const_iterator itr = mpTabRangesArray->begin(), itrEnd = mpTabRangesArray->end();
++    for (; itr != itrEnd; ++itr)
++    {
++        ScFlatBoolRowSegments::RangeData aData;
++        ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
++        for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
++        {
++            if (!aData.mbValue)
++                continue;
++
++            nCellCount += aData.mnRow2 - aData.mnRow1 + 1;
++        }
++    }
++
++    ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
++
++    Fraction aZoom(1, 1);
++    itr = mpTabRangesArray->begin();
++    sal_uInt32 nProgressStart = 0;
++    for (; itr != itrEnd; ++itr)
++    {
++        SCTAB nTab = itr->mnTab;
++        if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++            continue;
++
++        ScFlatBoolRowSegments::RangeData aData;
++        ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
++        for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
++        {
++            if (!aData.mbValue)
++                continue;
++
++            mrDoc.pTab[nTab]->SetOptimalHeight(
++                aData.mnRow1, aData.mnRow2, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
++
++            nProgressStart += aData.mnRow2 - aData.mnRow1 + 1;
++        }
++    }
++}
++
++void ScDocRowHeightUpdater::updateAll()
++{
++    sal_uInt32 nCellCount = 0;
++    for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
++    {
++        if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++            continue;
++
++        nCellCount += mrDoc.pTab[nTab]->GetWeightedCount();
++    }
++
++    ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
++
++    Fraction aZoom(1, 1);
++    ULONG nProgressStart = 0;
++    for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
++    {
++        if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++            continue;
++
++        mrDoc.pTab[nTab]->SetOptimalHeight(
++            0, MAXROW, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
++
++        nProgressStart += mrDoc.pTab[nTab]->GetWeightedCount();
++    }
++}
+diff --git sc/source/core/data/docparam.cxx sc/source/core/data/docparam.cxx
+new file mode 100644
+index 0000000..0644dd6
+--- /dev/null
++++ sc/source/core/data/docparam.cxx
+@@ -0,0 +1,40 @@
++/*************************************************************************
++ *
++ * 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: document.hxx,v $
++ * $Revision: 1.115.36.9 $
++ *
++ * 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 ---------------------------------------------------------------
++
++#include "docparam.hxx"
++
++ScColWidthParam::ScColWidthParam() :
++    mnMaxTextRow(-1), mnMaxTextLen(0), mbSimpleText(true) {}
++
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index a783519..65a3cc7 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -3269,14 +3269,14 @@ ULONG ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab ) const
+ 
+ 
+ USHORT ScDocument::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, OutputDevice* pDev,
+-                                        double nPPTX, double nPPTY,
+-                                        const Fraction& rZoomX, const Fraction& rZoomY,
+-                                        BOOL bFormula, const ScMarkData* pMarkData,
+-                                        BOOL bSimpleTextImport )
++                                       double nPPTX, double nPPTY,
++                                       const Fraction& rZoomX, const Fraction& rZoomY,
++                                       BOOL bFormula, const ScMarkData* pMarkData,
++                                       const ScColWidthParam* pParam )
+ {
+     if ( ValidTab(nTab) && pTab[nTab] )
+         return pTab[nTab]->GetOptimalColWidth( nCol, pDev, nPPTX, nPPTY,
+-            rZoomX, rZoomY, bFormula, pMarkData, bSimpleTextImport );
++            rZoomX, rZoomY, bFormula, pMarkData, pParam );
+     DBG_ERROR("Falsche Tabellennummer");
+     return 0;
+ }
+diff --git sc/source/core/data/makefile.mk sc/source/core/data/makefile.mk
+index 5893136..5a08a9b 100644
+--- sc/source/core/data/makefile.mk
++++ sc/source/core/data/makefile.mk
+@@ -74,6 +74,7 @@ SLOFILES =  \
+     $(SLO)$/documen8.obj \
+     $(SLO)$/documen9.obj \
+     $(SLO)$/document.obj \
++    $(SLO)$/docparam.obj \
+         $(SLO)$/dpcachetable.obj \
+         $(SLO)$/dpdimsave.obj \
+         $(SLO)$/dpgroup.obj \
+diff --git sc/source/core/data/segmenttree.cxx sc/source/core/data/segmenttree.cxx
+index 98c5032..b86aca8 100644
+--- sc/source/core/data/segmenttree.cxx
++++ sc/source/core/data/segmenttree.cxx
+@@ -66,9 +66,14 @@ public:
+ 
+     SCROW findLastNotOf(ValueType nValue) const;
+ 
++    // range iteration
++    bool getFirst(RangeData& rData);
++    bool getNext(RangeData& rData);
++
+ private:
+     typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type;
+     fst_type maSegments;
++    typename fst_type::const_iterator maItr;
+ };
+ 
+ template<typename _ValueType, typename _ExtValueType>
+@@ -175,6 +180,31 @@ SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType
+     return nPos;
+ }
+ 
++template<typename _ValueType, typename _ExtValueType>
++bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getFirst(RangeData& rData)
++{
++    maItr = maSegments.begin();
++    return getNext(rData);
++}
++
++template<typename _ValueType, typename _ExtValueType>
++bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getNext(RangeData& rData)
++{
++    typename fst_type::const_iterator itrEnd = maSegments.end();
++    if (maItr == itrEnd)
++        return false;
++
++    rData.mnPos1 = maItr->first;
++    rData.mnValue = maItr->second;
++
++    ++maItr;
++    if (maItr == itrEnd)
++        return false;
++
++    rData.mnPos2 = maItr->first - 1;
++    return true;
++}
++
+ // ============================================================================
+ 
+ class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>
+@@ -245,6 +275,37 @@ SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const
+ 
+ // ----------------------------------------------------------------------------
+ 
++ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments& rSegs) :
++    mrSegs(rSegs)
++{
++}
++
++bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData& rRange)
++{
++    ScFlatBoolSegmentsImpl::RangeData aData;
++    if (!mrSegs.mpImpl->getFirst(aData))
++        return false;
++
++    rRange.mnRow1  = static_cast<SCROW>(aData.mnPos1);
++    rRange.mnRow2  = static_cast<SCROW>(aData.mnPos2);
++    rRange.mbValue = static_cast<bool>(aData.mnValue);
++    return true;
++}
++
++bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData& rRange)
++{
++    ScFlatBoolSegmentsImpl::RangeData aData;
++    if (!mrSegs.mpImpl->getNext(aData))
++        return false;
++
++    rRange.mnRow1  = static_cast<SCROW>(aData.mnPos1);
++    rRange.mnRow2  = static_cast<SCROW>(aData.mnPos2);
++    rRange.mbValue = static_cast<bool>(aData.mnValue);
++    return true;
++}
++
++// ----------------------------------------------------------------------------
++
+ ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
+     mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXROW)))
+ {
+diff --git sc/source/core/data/table1.cxx sc/source/core/data/table1.cxx
+index 47fc6ff..e55582b 100644
+--- sc/source/core/data/table1.cxx
++++ sc/source/core/data/table1.cxx
+@@ -308,10 +308,10 @@ USHORT ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
+                                     double nPPTX, double nPPTY,
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bFormula, const ScMarkData* pMarkData,
+-                                    BOOL bSimpleTextImport )
++                                    const ScColWidthParam* pParam )
+ {
+     return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
+-        bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, bSimpleTextImport );
++        bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
+ }
+ 
+ long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
+diff --git sc/source/ui/docshell/dbdocimp.cxx sc/source/ui/docshell/dbdocimp.cxx
+index 112e35b..4e16c9c 100644
+--- sc/source/ui/docshell/dbdocimp.cxx
++++ sc/source/ui/docshell/dbdocimp.cxx
+@@ -271,7 +271,7 @@ BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
+     // ImportDoc - also used for Redo
+     ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
+     pImportDoc->InitUndo( pDoc, nTab, nTab );
+-    ScColumn::bDoubleAlloc = TRUE;
++    ScColumn::DoubleAllocSwitch aAllocSwitch(true);
+ 
+     //
+     //	get data from database into import document
+@@ -463,7 +463,6 @@ BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
+         DBG_ERROR("Unexpected exception in database");
+     }
+ 
+-    ScColumn::bDoubleAlloc = FALSE;
+     pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 );
+ 
+     //
+diff --git sc/source/ui/docshell/docsh.cxx sc/source/ui/docshell/docsh.cxx
+index 2cd4321..cc4c5bf 100644
+--- sc/source/ui/docshell/docsh.cxx
++++ sc/source/ui/docshell/docsh.cxx
+@@ -122,9 +122,11 @@
+ #include "optsolver.hxx"
+ #include "sheetdata.hxx"
+ #include "tabprotection.hxx"
++#include "docparam.hxx"
+ 
+ #include "docsh.hxx"
+ #include "docshimp.hxx"
++#include "sizedev.hxx"
+ #include <rtl/logfile.hxx>
+ 
+ #include <comphelper/processfactory.hxx>
+@@ -134,12 +136,18 @@
+ #include <com/sun/star/document/VbaEventId.hpp>
+ #include <basic/sbstar.hxx>
+ #include <basic/basmgr.hxx>
++
++#include <vector>
++#include <boost/shared_ptr.hpp>
++
+ using namespace com::sun::star;
+ using namespace com::sun::star::document::VbaEventId;
+ 
+ using namespace com::sun::star;
+ using ::rtl::OUString;
+ using ::rtl::OUStringBuffer;
++using ::boost::shared_ptr;
++using ::std::vector;
+ 
+ // STATIC DATA -----------------------------------------------------------
+ 
+@@ -966,12 +974,13 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+     // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
+     BOOL bSetColWidths = FALSE;
+     BOOL bSetSimpleTextColWidths = FALSE;
+-    BOOL bSimpleColWidth[MAXCOLCOUNT];
+-    memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(BOOL) );
++    ScColWidthParam aColWidthParam[MAXCOLCOUNT];
+     ScRange aColWidthRange;
+     // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
+     BOOL bSetRowHeights = FALSE;
+ 
++    vector<ScDocRowHeightUpdater::TabRanges> aRecalcRowRangesArray;
++
+     aConvFilterName.Erase(); //@ #BugId 54198
+ 
+     //	Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
+@@ -1170,8 +1179,10 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+                 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
+             }
+ 
++            ScDocRowHeightUpdater::TabRanges aRecalcRanges(0);
+             ULONG eError = DBaseImport( rMedium.GetPhysicalName(),
+-                    ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth );
++                    ScGlobal::GetCharsetValue(sItStr), aColWidthParam, *aRecalcRanges.mpRanges );
++            aRecalcRowRangesArray.push_back(aRecalcRanges);
+ 
+             if (eError != eERR_OK)
+             {
+@@ -1185,12 +1196,6 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+             aColWidthRange.aStart.SetRow( 1 );	// Spaltenheader nicht
+             bSetColWidths = TRUE;
+             bSetSimpleTextColWidths = TRUE;
+-            // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE
+-            for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ )
+-            {
+-                if ( !bSimpleColWidth[nCol] )
+-                    bSetRowHeights = TRUE;
+-            }
+         }
+         else if (aFltName.EqualsAscii(pFilterDif))
+         {
+@@ -1404,9 +1409,12 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+             {
+                 for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
+                 {
++                    if (!bSetSimpleTextColWidths)
++                        aColWidthParam[nCol].mbSimpleText = false;
++
+                     USHORT nWidth = aDocument.GetOptimalColWidth(
+                         nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, FALSE, &aMark,
+-                        (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) );
++                        &aColWidthParam[nCol] );
+                     aDocument.SetColWidth( nCol, nTab,
+                         nWidth + (USHORT)ScGlobal::nLastColWidthExtra );
+                 }
+@@ -1418,11 +1426,25 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+ //					nPPTX, nPPTY, aZoom, aZoom, FALSE );
+ //			}
+         }
+-        if ( bSetRowHeights )
+-            UpdateAllRowHeights();		// with vdev or printer, depending on configuration
++
++        if (bSetRowHeights)
++        {
++            // Update all rows in all tables.
++            ScSizeDeviceProvider aProv(this);
++            ScDocRowHeightUpdater aUpdater(aDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), NULL);
++            aUpdater.update();
++        }
++        else if (!aRecalcRowRangesArray.empty())
++        {
++            // Update only specified row ranges for better performance.
++            ScSizeDeviceProvider aProv(this);
++            ScDocRowHeightUpdater aUpdater(aDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &aRecalcRowRangesArray);
++            aUpdater.update();
++        }
+     }
+     FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
+ 
++
+     // #73762# invalidate eventually temporary table areas
+     if ( bRet )
+         aDocument.InvalidateTableArea();
+diff --git sc/source/ui/docshell/docsh8.cxx sc/source/ui/docshell/docsh8.cxx
+index 0db7d6b..1156518 100644
+--- sc/source/ui/docshell/docsh8.cxx
++++ sc/source/ui/docshell/docsh8.cxx
+@@ -86,6 +86,8 @@
+ #include "patattr.hxx"
+ #include "scitems.hxx"
+ #include "docpool.hxx"
++#include "segmenttree.hxx"
++#include "docparam.hxx"
+ 
+ #include <vector>
+ 
+@@ -304,9 +306,11 @@ static void lcl_setScalesToColumns(ScDocument& rDoc, const vector<long>& rScales
+     }
+ }
+ 
+-ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
+-                                BOOL bSimpleColWidth[MAXCOLCOUNT] )
++ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet, 
++                               ScColWidthParam aColWidthParam[MAXCOLCOUNT], ScFlatBoolRowSegments& rRowHeightsRecalc )
+ {
++    ScColumn::DoubleAllocSwitch aAllocSwitch(true);
++
+     ULONG nErr = eERR_OK;
+     long i;
+ 
+@@ -429,16 +433,33 @@ ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
+         BOOL bEnd = FALSE;
+         while ( !bEnd && xRowSet->next() )
+         {
++            bool bSimpleRow = true;
+             if ( nRow <= MAXROW )
+             {
+                 SCCOL nCol = 0;
+                 for (i=0; i<nColCount; i++)
+                 {
++                    ScDatabaseDocUtil::StrData aStrData;
+                     ScDatabaseDocUtil::PutData( &aDocument, nCol, nRow, 0,
+                                                 xRow, i+1, pTypeArr[i], FALSE,
+-                                                &bSimpleColWidth[nCol] );
++                                                &aStrData );
++
++                    if (aStrData.mnStrLength > aColWidthParam[nCol].mnMaxTextLen)
++                    {
++                        aColWidthParam[nCol].mnMaxTextLen = aStrData.mnStrLength;
++                        aColWidthParam[nCol].mnMaxTextRow = nRow;
++                    }
++
++                    if (!aStrData.mbSimpleText)
++                    {    
++                        bSimpleRow = false;
++                        aColWidthParam[nCol].mbSimpleText = false;
++                    }
++
+                     ++nCol;
+                 }
++                if (!bSimpleRow)
++                    rRowHeightsRecalc.setTrue(nRow, nRow);
+                 ++nRow;
+             }
+             else		// past the end of the spreadsheet
+diff --git sc/source/ui/docshell/impex.cxx sc/source/ui/docshell/impex.cxx
+index 8dc8646..83fdc04 100644
+--- sc/source/ui/docshell/impex.cxx
++++ sc/source/ui/docshell/impex.cxx
+@@ -1194,8 +1194,7 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm )
+     if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+         rStrm.StartReadingUnicodeText();
+ 
+-    BOOL bOld = ScColumn::bDoubleAlloc;
+-    ScColumn::bDoubleAlloc = TRUE;
++    ScColumn::DoubleAllocSwitch aAllocSwitch(true);
+ 
+     SCCOL nStartCol = aRange.aStart.Col();
+     SCCOL nEndCol = aRange.aEnd.Col();
+@@ -1396,7 +1395,6 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm )
+         bDetermineRange = !bDetermineRange;     // toggle
+     } while (!bDetermineRange);
+ 
+-    ScColumn::bDoubleAlloc = bOld;
+     pDoc->DoColResize( nTab, nStartCol, nEndCol, 0 );
+ 
+     delete pEnglishTransliteration;
+diff --git sc/source/ui/inc/docsh.hxx sc/source/ui/inc/docsh.hxx
+index 32539da..a317cfa 100644
+--- sc/source/ui/inc/docsh.hxx
++++ sc/source/ui/inc/docsh.hxx
+@@ -74,6 +74,8 @@ class ScImportOptions;
+ class ScDocShellModificator;
+ class ScOptSolverSave;
+ class ScSheetSaveData;
++class ScFlatBoolRowSegments;
++struct ScColWidthParam;
+ 
+ namespace sfx2 { class FileDialogHelper; }
+ struct DocShell_Impl;
+@@ -154,7 +156,7 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
+     SC_DLLPRIVATE SCTAB			GetSaveTab();
+ 
+     SC_DLLPRIVATE ULONG			DBaseImport( const String& rFullFileName, CharSet eCharSet,
+-                                 BOOL bSimpleColWidth[MAXCOLCOUNT] );
++                                             ScColWidthParam aColWidthParam[MAXCOLCOUNT], ScFlatBoolRowSegments& rRowHeightsRecalc );
+     SC_DLLPRIVATE ULONG			DBaseExport( const String& rFullFileName, CharSet eCharSet,
+                                  BOOL& bHasMemo );
+ 


More information about the ooo-build-commit mailing list