[Libreoffice-commits] core.git: Branch 'libreoffice-4-3' - sc/inc sc/source

Eike Rathke erack at redhat.com
Mon May 26 16:47:32 PDT 2014


 sc/inc/attarray.hxx             |   21 ++++++++++++++++++
 sc/inc/column.hxx               |    2 -
 sc/source/core/data/column2.cxx |   45 +++++++++++++++++++++++++++++++++-------
 sc/source/core/data/table1.cxx  |    4 +--
 4 files changed, 62 insertions(+), 10 deletions(-)

New commits:
commit 1baac7f17b024b15d79bbb9e89e68b2863c150e9
Author: Eike Rathke <erack at redhat.com>
Date:   Tue May 27 01:34:37 2014 +0200

    resolved fdo#79228 resync ScPatternAttr if changed in GetNeededSize()
    
    Change-Id: Ida47df6223a20939ad5971dc00b8f3462a92dd3e
    (cherry picked from commit a1dedadbf0d87a1db24e9b336257678e059882f0)

diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx
index 08e3c5a..9b6464b 100644
--- a/sc/inc/attarray.hxx
+++ b/sc/inc/attarray.hxx
@@ -206,6 +206,7 @@ class ScAttrIterator
 public:
     inline              ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd );
     inline const ScPatternAttr* Next( SCROW& rTop, SCROW& rBottom );
+    inline const ScPatternAttr* Resync( SCROW nRow, SCROW& rTop, SCROW& rBottom );
     SCROW               GetNextRow() const { return nRow; }
 };
 
@@ -236,6 +237,26 @@ inline const ScPatternAttr* ScAttrIterator::Next( SCROW& rTop, SCROW& rBottom )
     return pRet;
 }
 
+inline const ScPatternAttr* ScAttrIterator::Resync( SCROW nRowP, SCROW& rTop, SCROW& rBottom )
+{
+    nRow = nRowP;
+    // Chances are high that the pattern changed on nRowP introduced a span
+    // starting right there. Assume that Next() was called so nPos already
+    // advanced. Another high chance is that the change extended a previous or
+    // next pattern. In all these cases we don't need to search.
+    if (3 <= nPos && nPos <= pArray->nCount && pArray->pData[nPos-3].nRow < nRowP &&
+            nRowP <= pArray->pData[nPos-2].nRow)
+        nPos -= 2;
+    else if (2 <= nPos && nPos <= pArray->nCount && pArray->pData[nPos-2].nRow < nRowP &&
+            nRowP <= pArray->pData[nPos-1].nRow)
+        --nPos;
+    else if (pArray->nCount > 0 && nRowP <= pArray->pData[0].nRow)
+        nPos = 0;
+    else
+        pArray->Search( nRowP, nPos );
+    return Next( rTop, rBottom);
+}
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 4212056..547fd14 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -445,7 +445,7 @@ public:
     long GetNeededSize(
         SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY,
         const Fraction& rZoomX, const Fraction& rZoomY,
-        bool bWidth, const ScNeededSizeOptions& rOptions) const;
+        bool bWidth, const ScNeededSizeOptions& rOptions, const ScPatternAttr** pPatternChange ) const;
 
     sal_uInt16 GetOptimalColWidth(
         OutputDevice* pDev, double nPPTX, double nPPTY,
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 7e5a4a6..763e658 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -86,7 +86,8 @@ inline bool IsAmbiguousScript( sal_uInt8 nScript )
 long ScColumn::GetNeededSize(
     SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY,
     const Fraction& rZoomX, const Fraction& rZoomY,
-    bool bWidth, const ScNeededSizeOptions& rOptions ) const
+    bool bWidth, const ScNeededSizeOptions& rOptions,
+    const ScPatternAttr** ppPatternChange ) const
 {
     std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
     sc::CellStoreType::const_iterator it = aPos.first;
@@ -148,9 +149,32 @@ long ScColumn::GetNeededSize(
     SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
     sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
     // #i111387# disable automatic line breaks only for "General" number format
-    if (bBreak && aCell.hasNumeric() && ( nFormat % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
+    if (bBreak && ( nFormat % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
     {
-        bBreak = false;
+        // If a formula cell needs to be interpreted during aCell.hasNumeric()
+        // to determine the type, the pattern may get invalidated because the
+        // result may set a number format. In which case there's also the
+        // General format not set anymore..
+        bool bMayInvalidatePattern = (aCell.meType == CELLTYPE_FORMULA);
+        const ScPatternAttr* pOldPattern = pPattern;
+        bool bNumeric = aCell.hasNumeric();
+        if (bMayInvalidatePattern)
+        {
+            pPattern = pAttrArray->GetPattern( nRow );
+            if (ppPatternChange)
+                *ppPatternChange = pPattern;    // XXX caller may have to check for change!
+        }
+        if (bNumeric)
+        {
+            if (!bMayInvalidatePattern || pPattern == pOldPattern)
+                bBreak = false;
+            else
+            {
+                nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
+                if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+                    bBreak = false;
+            }
+        }
     }
 
     //  get other attributes from pattern and conditional formatting
@@ -689,9 +713,9 @@ sal_uInt16 ScColumn::GetOptimalColWidth(
                     const ScPatternAttr* pPattern = GetPattern(nRow);
                     aOptions.pPattern = pPattern;
                     aOptions.bGetFont = (pPattern != pOldPattern || nScript != nOldScript);
-                    sal_uInt16 nThis = (sal_uInt16) GetNeededSize(
-                        nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, true, aOptions);
                     pOldPattern = pPattern;
+                    sal_uInt16 nThis = (sal_uInt16) GetNeededSize(
+                        nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, true, aOptions, &pOldPattern);
                     if (nThis)
                     {
                         if (nThis > nWidth || !bFound)
@@ -763,7 +787,6 @@ void ScColumn::GetOptimalHeight(
     //  with conditional formatting, always consider the individual cells
 
     const ScPatternAttr* pPattern = aIter.Next(nStart,nEnd);
-    ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
     while ( pPattern )
     {
         const ScMergeAttr*      pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
@@ -902,11 +925,19 @@ void ScColumn::GetOptimalHeight(
                         if (rCxt.isForceAutoSize() || !(pDocument->GetRowFlags(nRow, nTab) & CR_MANUALSIZE) )
                         {
                             aOptions.pPattern = pPattern;
+                            const ScPatternAttr* pOldPattern = pPattern;
                             sal_uInt16 nHeight = (sal_uInt16)
                                     ( GetNeededSize( nRow, rCxt.getOutputDevice(), rCxt.getPPTX(), rCxt.getPPTY(),
-                                                        rCxt.getZoomX(), rCxt.getZoomY(), false, aOptions ) / rCxt.getPPTY() );
+                                                        rCxt.getZoomX(), rCxt.getZoomY(), false, aOptions,
+                                                        &pPattern) / rCxt.getPPTY() );
                             if (nHeight > pHeight[nRow-nStartRow])
                                 pHeight[nRow-nStartRow] = nHeight;
+                            // Pattern changed due to calculation? => sync.
+                            if (pPattern != pOldPattern)
+                            {
+                                pPattern = aIter.Resync( nRow, nStart, nEnd);
+                                nNextEnd = 0;
+                            }
                         }
                     }
                 }
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index e603337..b7e020f 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -451,7 +451,7 @@ long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
     aOptions.bTotalSize  = bTotalSize;
 
     return aCol[nCol].GetNeededSize
-        ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions );
+        ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions, NULL );
 }
 
 bool ScTable::SetOptimalHeight(
@@ -1802,7 +1802,7 @@ void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, d
 
         Fraction aZoom(1,1);
         nPixel = aCol[rCol].GetNeededSize(
-            nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions );
+            nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions, NULL );
 
         aCol[rCol].SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
     }


More information about the Libreoffice-commits mailing list