diff options
author | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-01-15 10:46:42 +0000 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-01-23 22:11:31 +0100 |
commit | 7e774c56ef6e261e92e78db52ccf79b046ab2a98 (patch) | |
tree | e1f78404ab767f81a8fe64af035912a85151a75a /sc/source | |
parent | d8af51f9c521dca999c22a025e625f09002907b6 (diff) |
don't always invalidate the entire width of the calc window
If know the max width affected we can avoid redrawing much of
the row
LTR cell edits, deletes, single line paste
Change-Id: Ib7e3d8bfa3a5ce7df97f28bcf7858b3abcb752a4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162408
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162483
Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/core/tool/hints.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 27 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh3.cxx | 41 | ||||
-rw-r--r-- | sc/source/ui/inc/docsh.hxx | 11 | ||||
-rw-r--r-- | sc/source/ui/inc/tabview.hxx | 3 | ||||
-rw-r--r-- | sc/source/ui/view/tabview3.cxx | 34 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwsh5.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun3.cxx | 18 |
8 files changed, 111 insertions, 35 deletions
diff --git a/sc/source/core/tool/hints.cxx b/sc/source/core/tool/hints.cxx index 06ac946d9b6e..a3be243750a4 100644 --- a/sc/source/core/tool/hints.cxx +++ b/sc/source/core/tool/hints.cxx @@ -22,9 +22,10 @@ // ScPaintHint - info what has to be repainted -ScPaintHint::ScPaintHint( const ScRange& rRng, PaintPartFlags nPaint ) : +ScPaintHint::ScPaintHint( const ScRange& rRng, PaintPartFlags nPaint, tools::Long nMaxWidthAffectedHint ) : aRange( rRng ), - nParts( nPaint ) + nParts( nPaint ), + nWidthAffectedHint(nMaxWidthAffectedHint) { } diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 1a8d902bea19..21aee819174b 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -671,6 +671,26 @@ bool ScDocFunc::DeleteContents( return true; } +tools::Long ScDocShell::GetPixelWidthHint(const ScAddress& rPos) +{ + ScViewData* pViewData = GetViewData(); + if (!pViewData) + return -1; + + ScSizeDeviceProvider aProv(this); + OutputDevice* pDev = aProv.GetDevice(); // has pixel MapMode + double nPPTX = aProv.GetPPTX(); + double nPPTY = aProv.GetPPTY(); + + ScDocument& rDoc = GetDocument(); + Fraction aInvX(pViewData->GetZoomX().GetDenominator(), + pViewData->GetZoomX().GetNumerator()); + Fraction aInvY(pViewData->GetZoomY().GetDenominator(), + pViewData->GetZoomY().GetNumerator()); + return rDoc.GetNeededSize(rPos.Col(), rPos.Row(), rPos.Tab(), pDev, + nPPTX, nPPTY, aInvX, aInvY, true /*bWidth*/); +} + bool ScDocFunc::DeleteCell( const ScAddress& rPos, const ScMarkData& rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi ) { @@ -719,6 +739,7 @@ bool ScDocFunc::DeleteCell( pDataSpans = sc::DocFuncUtil::getNonEmptyCellSpans(rDoc, rMark, rPos); } + tools::Long nBefore(rDocShell.GetPixelWidthHint(rPos)); rDoc.DeleteArea(rPos.Col(), rPos.Row(), rPos.Col(), rPos.Row(), rMark, nFlags); if (bRecord) @@ -731,7 +752,7 @@ bool ScDocFunc::DeleteCell( if (!AdjustRowHeight(rPos, true, bApi)) rDocShell.PostPaint( rPos.Col(), rPos.Row(), rPos.Tab(), rPos.Col(), rPos.Row(), rPos.Tab(), - PaintPartFlags::Grid, nExtFlags); + PaintPartFlags::Grid, nExtFlags, nBefore); aModificator.SetDocumentModified(); @@ -833,7 +854,9 @@ bool ScDocFunc::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, con aOldValues.push_back(aOldValue); } + tools::Long nBefore(rDocShell.GetPixelWidthHint(rPos)); o_rbNumFmtSet = rDoc.SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText ); + tools::Long nAfter(rDocShell.GetPixelWidthHint(rPos)); if (bUndo) { @@ -845,7 +868,7 @@ bool ScDocFunc::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, con if ( bEditDeleted || rDoc.HasAttrib( ScRange(rPos), HasAttrFlags::NeedHeight ) ) AdjustRowHeight( ScRange(rPos), true, bApi ); - rDocShell.PostPaintCell( rPos ); + rDocShell.PostPaintCell( rPos, std::max(nBefore, nAfter) ); aModificator.SetDocumentModified(); // notify input handler here the same way as in PutCell diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx index 96546d11a5fe..39b74be3f466 100644 --- a/sc/source/ui/docshell/docsh3.cxx +++ b/sc/source/ui/docshell/docsh3.cxx @@ -100,13 +100,13 @@ void ScDocShell::PostDataChanged() void ScDocShell::PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, - sal_uInt16 nExtFlags ) + sal_uInt16 nExtFlags, tools::Long nMaxWidthAffectedHint ) { ScRange aRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab); - PostPaint(aRange, nPart, nExtFlags); + PostPaint(aRange, nPart, nExtFlags, nMaxWidthAffectedHint); } -void ScDocShell::PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sal_uInt16 nExtFlags ) +void ScDocShell::PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sal_uInt16 nExtFlags, tools::Long nMaxWidthAffectedHint ) { ScRangeList aPaintRanges; std::set<SCTAB> aTabsInvalidated; @@ -118,9 +118,17 @@ void ScDocShell::PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sa SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row(); SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = std::min<SCTAB>(nMaxTab, rRange.aEnd.Tab()); - if (!m_pDocument->ValidCol(nCol1)) nCol1 = m_pDocument->MaxCol(); + if (!m_pDocument->ValidCol(nCol1)) + { + nMaxWidthAffectedHint = -1; // Hint no longer valid + nCol1 = m_pDocument->MaxCol(); + } if (!m_pDocument->ValidRow(nRow1)) nRow1 = m_pDocument->MaxRow(); - if (!m_pDocument->ValidCol(nCol2)) nCol2 = m_pDocument->MaxCol(); + if (!m_pDocument->ValidCol(nCol2)) + { + nMaxWidthAffectedHint = -1; // Hint no longer valid + nCol2 = m_pDocument->MaxCol(); + } if (!m_pDocument->ValidRow(nRow2)) nRow2 = m_pDocument->MaxRow(); if ( m_pPaintLockData ) @@ -143,8 +151,16 @@ void ScDocShell::PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sa if (nExtFlags & SC_PF_LINES) // respect space for lines { //! check for hidden columns/rows! - if (nCol1>0) --nCol1; - if (nCol2<m_pDocument->MaxCol()) ++nCol2; + if (nCol1 > 0) + { + nMaxWidthAffectedHint = -1; // Hint no longer valid + --nCol1; + } + if (nCol2 < m_pDocument->MaxCol()) + { + nMaxWidthAffectedHint = -1; // Hint no longer valid + ++nCol2; + } if (nRow1>0) --nRow1; if (nRow2<m_pDocument->MaxRow()) ++nRow2; } @@ -166,6 +182,7 @@ void ScDocShell::PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sa { nCol1 = 0; nCol2 = m_pDocument->MaxCol(); + nMaxWidthAffectedHint = -1; // Hint no longer valid } } aPaintRanges.push_back(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2)); @@ -173,7 +190,7 @@ void ScDocShell::PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sa aTabsInvalidated.insert(nTabNum); } - Broadcast(ScPaintHint(aPaintRanges.Combine(), nPart)); + Broadcast(ScPaintHint(aPaintRanges.Combine(), nPart, nMaxWidthAffectedHint)); // LOK: we are supposed to update the row / columns headers (and actually // the document size too - cell size affects that, obviously) @@ -190,14 +207,14 @@ void ScDocShell::PostPaintGridAll() PostPaint( 0,0,0, m_pDocument->MaxCol(),m_pDocument->MaxRow(),MAXTAB, PaintPartFlags::Grid ); } -void ScDocShell::PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab ) +void ScDocShell::PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab, tools::Long nMaxWidthAffectedHint ) { - PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PaintPartFlags::Grid, SC_PF_TESTMERGE ); + PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PaintPartFlags::Grid, SC_PF_TESTMERGE, nMaxWidthAffectedHint ); } -void ScDocShell::PostPaintCell( const ScAddress& rPos ) +void ScDocShell::PostPaintCell( const ScAddress& rPos, tools::Long nMaxWidthAffectedHint ) { - PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() ); + PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab(), nMaxWidthAffectedHint ); } void ScDocShell::PostPaintExtras() diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index eb9a3450ad22..d476ce15222e 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -313,13 +313,16 @@ public: void PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos ); + tools::Long GetPixelWidthHint(const ScAddress& rPos); + void PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, - sal_uInt16 nExtFlags = 0 ); - void PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sal_uInt16 nExtFlags = 0 ); + sal_uInt16 nExtFlags = 0, tools::Long nMaxWidthAffectedHint = -1 ); + void PostPaint( const ScRangeList& rRanges, PaintPartFlags nPart, sal_uInt16 nExtFlags = 0, + tools::Long nMaxWidthAffectedHint = -1 ); - void PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab ); - void PostPaintCell( const ScAddress& rPos ); + void PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab, tools::Long nMaxWidthAffectedHint = -1); + void PostPaintCell( const ScAddress& rPos, tools::Long nMaxWidthAffectedHint = -1); void PostPaintGridAll(); void PostPaintExtras(); diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index 9c6a2138e6d7..93f1b60e5759 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -483,7 +483,8 @@ public: // Drawing void PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, - ScUpdateMode eMode = ScUpdateMode::All ); + ScUpdateMode eMode = ScUpdateMode::All, + tools::Long nMaxWidthAffectedHint = -1 ); void PaintGrid(); diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 444b78b20b64..0d4086bfb4a2 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -2364,7 +2364,7 @@ void ScTabView::UpdateFormulas(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, // PaintArea - repaint block void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, - ScUpdateMode eMode ) + ScUpdateMode eMode, tools::Long nMaxWidthAffectedHint ) { SCCOL nCol1; SCROW nRow1; @@ -2442,20 +2442,32 @@ void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCRO if ( eMode == ScUpdateMode::All ) { - if (bIsTiledRendering) + if (nMaxWidthAffectedHint != -1) { - // When a cell content is deleted we have no clue about - // the width of the embedded text. - // Anyway, clients will ask only for tiles that overlaps - // the visible area. - // Remember that wsd expects int and that aEnd.X() is - // in pixels and will be converted in twips, before performing - // the lok callback, so we need to avoid that an overflow occurs. - aEnd.setX( std::numeric_limits<int>::max() / 1000 ); + // If we know the max text width affected then just invalidate + // the max of the cell width and hint of affected cell width + // (where affected with is in terms of max width of optimal cell + // width for before/after change) + tools::Long nCellWidth = std::abs(aEnd.X() - aStart.X()); + aEnd.setX(aStart.getX() + std::max(nCellWidth, nMaxWidthAffectedHint) * nLayoutSign); } else { - aEnd.setX( bLayoutRTL ? 0 : pGridWin[i]->GetOutputSizePixel().Width() ); + if (bIsTiledRendering) + { + // When a cell content is deleted we have no clue about + // the width of the embedded text. + // Anyway, clients will ask only for tiles that overlaps + // the visible area. + // Remember that wsd expects int and that aEnd.X() is + // in pixels and will be converted in twips, before performing + // the lok callback, so we need to avoid that an overflow occurs. + aEnd.setX( std::numeric_limits<int>::max() / 1000 ); + } + else + { + aEnd.setX( bLayoutRTL ? 0 : pGridWin[i]->GetOutputSizePixel().Width() ); + } } } aEnd.AdjustX( -nLayoutSign ); diff --git a/sc/source/ui/view/tabvwsh5.cxx b/sc/source/ui/view/tabvwsh5.cxx index fab96304f39f..0cd44d2caf7e 100644 --- a/sc/source/ui/view/tabvwsh5.cxx +++ b/sc/source/ui/view/tabvwsh5.cxx @@ -57,12 +57,15 @@ void ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) if (nParts & PaintPartFlags::Size) RepeatResize(); //! InvalidateBorder ??? + const tools::Long nWidthAffectedHint = pPaintHint->GetMaxWidthAffectedHint(); if (nParts & PaintPartFlags::Grid) PaintArea( pPaintHint->GetStartCol(), pPaintHint->GetStartRow(), - pPaintHint->GetEndCol(), pPaintHint->GetEndRow() ); + pPaintHint->GetEndCol(), pPaintHint->GetEndRow(), + ScUpdateMode::All, nWidthAffectedHint ); if (nParts & PaintPartFlags::Marks) PaintArea( pPaintHint->GetStartCol(), pPaintHint->GetStartRow(), - pPaintHint->GetEndCol(), pPaintHint->GetEndRow(), ScUpdateMode::Marks ); + pPaintHint->GetEndCol(), pPaintHint->GetEndRow(), + ScUpdateMode::Marks, nWidthAffectedHint ); if (nParts & PaintPartFlags::Left) PaintLeftArea( pPaintHint->GetStartRow(), pPaintHint->GetEndRow() ); if (nParts & PaintPartFlags::Top) diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 7a6403237b89..fb0e469d5205 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -1262,6 +1262,11 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc, } } + const bool bSingleCellBefore = nStartCol == nEndCol && + nStartRow == nEndRow && + nStartTab == nEndTab; + tools::Long nBeforeHint(bSingleCellBefore ? pDocSh->GetPixelWidthHint(ScAddress(nStartCol, nStartRow, nStartTab)) : -1); + sal_uInt16 nExtFlags = 0; pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ); // content before the change @@ -1437,9 +1442,20 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc, nPaint |= PaintPartFlags::Left; nUndoEndRow = rDoc.MaxRow(); // just for drawing ! } + + tools::Long nMaxWidthAffectedHint = -1; + const bool bSingleCellAfter = nStartCol == nUndoEndCol && + nStartRow == nUndoEndRow && + nStartTab == nEndTab; + if (bSingleCellBefore && bSingleCellAfter) + { + tools::Long nAfterHint(pDocSh->GetPixelWidthHint(ScAddress(nStartCol, nStartRow, nStartTab))); + nMaxWidthAffectedHint = std::max(nBeforeHint, nAfterHint); + } + pDocSh->PostPaint( ScRange(nStartCol, nStartRow, nStartTab, nUndoEndCol, nUndoEndRow, nEndTab), - nPaint, nExtFlags); + nPaint, nExtFlags, nMaxWidthAffectedHint); // AdjustBlockHeight has already been called above aModificator.SetDocumentModified(); |