Kaydet (Commit) a1dedadb authored tarafından Eike Rathke's avatar Eike Rathke

resolved fdo#79228 resync ScPatternAttr if changed in GetNeededSize()

Change-Id: Ida47df6223a20939ad5971dc00b8f3462a92dd3e
üst 467a0d62
......@@ -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: */
......@@ -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,
......
......@@ -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;
}
}
}
}
......
......@@ -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));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment