diff options
author | Eike Rathke <erack@redhat.com> | 2014-05-27 01:34:37 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2014-05-27 01:44:03 +0200 |
commit | a1dedadbf0d87a1db24e9b336257678e059882f0 (patch) | |
tree | 2f5ef61e59ae414f786830eb8be975eed217675a | |
parent | 467a0d624df1a62b8fa2b28d587c0b42ea3b3e04 (diff) |
resolved fdo#79228 resync ScPatternAttr if changed in GetNeededSize()
Change-Id: Ida47df6223a20939ad5971dc00b8f3462a92dd3e
-rw-r--r-- | sc/inc/attarray.hxx | 21 | ||||
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 45 | ||||
-rw-r--r-- | sc/source/core/data/table1.cxx | 4 |
4 files changed, 62 insertions, 10 deletions
diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index 08e3c5a2d90c..9b6464b37247 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 421205650886..547fd147b3ca 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 7e5a4a67ca3e..763e6584e494 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 e6033373765d..b7e020f5a04b 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)); } |