diff options
author | Dennis Francis <dennis.francis@collabora.com> | 2020-05-19 10:41:53 +0530 |
---|---|---|
committer | Dennis Francis <dennis.francis@collabora.com> | 2020-07-04 15:29:47 +0200 |
commit | 954ec00ccd500ac7dc153032cb5dff7e7ba008b2 (patch) | |
tree | 46793483b558ab9f0e01ec7384a35366c7dba259 /sc | |
parent | 2c798d6715194e910cef9cad1039f464d86dc06f (diff) |
lokit: scPrintTwipsMsgs: Extend the tiled-area limits...
if the client visible area is "close" to these limits. Also
send tile-invalidations for the new area uncovered.
** All this is done only if the flag scPrintTwipsMsgs is set.
Change-Id: I3d6b8c6aaae1eb934030c5bdbc1094dc8be16a9f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96971
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
(cherry picked from commit d64a5efdb8a2db38a5339ae04eb13807ba944ea0)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97957
Tested-by: Jenkins
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/ui/inc/tabview.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/unoobj/docuno.cxx | 9 | ||||
-rw-r--r-- | sc/source/ui/view/tabview.cxx | 260 |
3 files changed, 270 insertions, 0 deletions
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index f7986b20cf2d..4f2a0aee30c5 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -596,6 +596,7 @@ public: /// @see ScModelObj::getSheetGeometryData() OString getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden, bool bFiltered, bool bGroups); + void extendTiledAreaIfNeeded(); static void OnLOKNoteStateChanged(const ScPostIt* pNote); diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index cd14cf8d0879..774509870c02 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -69,6 +69,7 @@ #include <com/sun/star/script/XInvocation.hpp> #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include <com/sun/star/beans/XFastPropertySet.hpp> +#include <comphelper/lok.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/profilezone.hxx> #include <comphelper/servicehelper.hxx> @@ -1001,6 +1002,14 @@ void ScModelObj::setClientVisibleArea(const tools::Rectangle& rRectangle) // Store the visible area so that we can use at places like shape insertion pViewData->setLOKVisibleArea(rRectangle); + + if (comphelper::LibreOfficeKit::isCompatFlagSet( + comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs)) + { + ScTabView* pTabView = pViewData->GetView(); + if (pTabView) + pTabView->extendTiledAreaIfNeeded(); + } } void ScModelObj::setOutlineState(bool bColumn, int nLevel, int nIndex, bool bHidden) diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index c21f60e61eb3..495848f46e50 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -2433,6 +2433,167 @@ void lcl_createGroupsData( } } +class ScRangeProvider +{ +public: + ScRangeProvider(const tools::Rectangle& rArea, bool bInPixels, + ScViewData& rViewData, SCCOLROW nEnlargeX = 0, + SCCOLROW nEnlargeY = 0): + mrViewData(rViewData), + mnEnlargeX(nEnlargeX), + mnEnlargeY(nEnlargeY) + { + tools::Rectangle aAreaPx = bInPixels ? rArea : + tools::Rectangle(rArea.Left() * mrViewData.GetPPTX(), + rArea.Top() * mrViewData.GetPPTY(), + rArea.Right() * mrViewData.GetPPTX(), + rArea.Bottom() * mrViewData.GetPPTY()); + calculateBounds(aAreaPx); + } + + const ScRange& getCellRange() const + { + return maRange; + } + + void getColPositions(long& rStartColPos, long& rEndColPos) const + { + rStartColPos = maBoundPositions.Left(); + rEndColPos = maBoundPositions.Right(); + } + + void getRowPositions(long& rStartRowPos, long& rEndRowPos) const + { + rStartRowPos = maBoundPositions.Top(); + rEndRowPos = maBoundPositions.Bottom(); + } + +private: + void calculateBounds(const tools::Rectangle& rAreaPx) + { + long nLeftPx = 0, nRightPx = 0; + SCCOLROW nStartCol = -1, nEndCol = -1; + calculateDimensionBounds(rAreaPx.Left(), rAreaPx.Right(), true, + nStartCol, nEndCol, nLeftPx, nRightPx, + mnEnlargeX, mrViewData); + long nTopPx = 0, nBottomPx = 0; + SCCOLROW nStartRow = -1, nEndRow = -1; + calculateDimensionBounds(rAreaPx.Top(), rAreaPx.Bottom(), false, + nStartRow, nEndRow, nTopPx, nBottomPx, + mnEnlargeY, mrViewData); + + maRange.aStart.Set(nStartCol, nStartRow, mrViewData.GetTabNo()); + maRange.aEnd.Set(nEndCol, nEndRow, mrViewData.GetTabNo()); + + maBoundPositions.SetLeft(nLeftPx); + maBoundPositions.SetRight(nRightPx); + maBoundPositions.SetTop(nTopPx); + maBoundPositions.SetBottom(nBottomPx); + } + + // All positions are in pixels. + static void calculateDimensionBounds(const long nStartPos, const long nEndPos, + bool bColumns, SCCOLROW& rStartIndex, + SCCOLROW& rEndIndex, long& rBoundStart, + long& rBoundEnd, SCCOLROW nEnlarge, + ScViewData& rViewData) + { + ScPositionHelper& rPosHelper = bColumns ? rViewData.GetLOKWidthHelper() : + rViewData.GetLOKHeightHelper(); + const auto& rStartNearest = rPosHelper.getNearestByPosition(nStartPos); + const auto& rEndNearest = rPosHelper.getNearestByPosition(nEndPos); + + ScBoundsProvider aBoundsProvider(rViewData, rViewData.GetTabNo(), bColumns); + aBoundsProvider.Compute(rStartNearest, rEndNearest, nStartPos, nEndPos); + aBoundsProvider.EnlargeBy(nEnlarge); + if (bColumns) + { + SCCOL nStartCol = -1, nEndCol = -1; + aBoundsProvider.GetStartIndexAndPosition(nStartCol, rBoundStart); + aBoundsProvider.GetEndIndexAndPosition(nEndCol, rBoundEnd); + rStartIndex = nStartCol; + rEndIndex = nEndCol; + } + else + { + SCROW nStartRow = -1, nEndRow = -1; + aBoundsProvider.GetStartIndexAndPosition(nStartRow, rBoundStart); + aBoundsProvider.GetEndIndexAndPosition(nEndRow, rBoundEnd); + rStartIndex = nStartRow; + rEndIndex = nEndRow; + } + } + +private: + + ScRange maRange; + tools::Rectangle maBoundPositions; + ScViewData& mrViewData; + SCCOLROW mnEnlargeX; + SCCOLROW mnEnlargeY; +}; + +void lcl_ExtendTiledDimension(bool bColumn, const SCCOLROW nEnd, const SCCOLROW nExtra, + ScTabView& rTabView, ScViewData& rViewData) +{ + ScDocument* pDoc = rViewData.GetDocument(); + // If we are approaching current max tiled row/col, signal a size changed event + // and invalidate the involved area + SCCOLROW nMaxTiledIndex = bColumn ? rViewData.GetMaxTiledCol() : rViewData.GetMaxTiledRow(); + SCCOLROW nHardLimit = !bColumn ? MAXTILEDROW : pDoc ? pDoc->MaxCol() : MAXCOL; + + if (nMaxTiledIndex >= nHardLimit) + return; + + if (nEnd <= nMaxTiledIndex - nExtra) // No need to extend. + return; + + ScDocShell* pDocSh = rViewData.GetDocShell(); + ScModelObj* pModelObj = pDocSh ? + comphelper::getUnoTunnelImplementation<ScModelObj>( pDocSh->GetModel() ) : nullptr; + Size aOldSize(0, 0); + if (pModelObj) + aOldSize = pModelObj->getDocumentSize(); + + SCCOLROW nNewMaxTiledIndex = std::min(std::max(nEnd, nMaxTiledIndex) + nExtra, nHardLimit); + + if (bColumn) + rViewData.SetMaxTiledCol(nNewMaxTiledIndex); + else + rViewData.SetMaxTiledRow(nNewMaxTiledIndex); + + Size aNewSize(0, 0); + if (pModelObj) + aNewSize = pModelObj->getDocumentSize(); + + if (aOldSize == aNewSize) + return; + + if (!pDocSh) + return; + + // New area extended to the right/bottom of the sheet after last col/row + // excluding overlapping area with aNewArea + tools::Rectangle aNewArea = bColumn ? + tools::Rectangle(aOldSize.getWidth(), 0, aNewSize.getWidth(), aNewSize.getHeight()): + tools::Rectangle(0, aOldSize.getHeight(), aNewSize.getWidth(), aNewSize.getHeight()); + + // Only invalidate if spreadsheet has extended to the right or bottom + if ((bColumn && aNewArea.getWidth()) || (!bColumn && aNewArea.getHeight())) + { + rTabView.UpdateSelectionOverlay(); + SfxLokHelper::notifyInvalidation(rViewData.GetViewShell(), aNewArea.toString()); + } + + // Provide size in the payload, so clients don't have to query for that. + std::stringstream ss; + ss << aNewSize.Width() << ", " << aNewSize.Height(); + OString sSize = ss.str().c_str(); + ScModelObj* pModel = comphelper::getUnoTunnelImplementation<ScModelObj>( + rViewData.GetViewShell()->GetCurrentDocument()); + SfxLokHelper::notifyDocumentSizeChanged(rViewData.GetViewShell(), sSize, pModel, false); +} + } // anonymous namespace void ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle, tools::JsonWriter& rJsonWriter) @@ -2833,4 +2994,103 @@ OString ScTabView::getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, return getJSONString(aTree).c_str(); } +void ScTabView::extendTiledAreaIfNeeded() +{ + SAL_INFO("sc.lok.header", + "extendTiledAreaIfNeeded: START: ClientView: ColRange[" + << mnLOKStartHeaderCol << "," << mnLOKEndHeaderCol + << "] RowRange[" << mnLOKStartHeaderRow << "," << mnLOKEndHeaderRow + << "] MaxTiledCol = " << aViewData.GetMaxTiledCol() + << " MaxTiledRow = " << aViewData.GetMaxTiledRow()); + + const tools::Rectangle rVisArea = aViewData.getLOKVisibleArea(); + if (rVisArea.Top() >= rVisArea.Bottom() || + rVisArea.Left() >= rVisArea.Right()) + return; + + // Needed for conditional updating of visible-range/formula. + tools::Rectangle aOldVisCellRange(mnLOKStartHeaderCol + 1, mnLOKStartHeaderRow + 1, + mnLOKEndHeaderCol, mnLOKEndHeaderRow); + + ScRangeProvider aRangeProvider(rVisArea, /* bInPixels */ false, aViewData, + /* nEnlargeX */ 2, /* nEnlargeY */ 2); + // Index bounds. + const ScRange& rCellRange = aRangeProvider.getCellRange(); + const SCCOL nStartCol = rCellRange.aStart.Col(); + const SCCOL nEndCol = rCellRange.aEnd.Col(); + const SCROW nStartRow = rCellRange.aStart.Row(); + const SCROW nEndRow = rCellRange.aEnd.Row(); + + // Column/Row positions. + long nStartColPos, nEndColPos, nStartRowPos, nEndRowPos; + aRangeProvider.getColPositions(nStartColPos, nEndColPos); + aRangeProvider.getRowPositions(nStartRowPos, nEndRowPos); + + ScPositionHelper& rWidthHelper = aViewData.GetLOKWidthHelper(); + ScPositionHelper& rHeightHelper = aViewData.GetLOKHeightHelper(); + + // Update mnLOKStartHeaderCol and mnLOKEndHeaderCol members. + // These are consulted in some ScGridWindow methods. + if (mnLOKStartHeaderCol != nStartCol) + { + rWidthHelper.removeByIndex(mnLOKStartHeaderCol); + rWidthHelper.insert(nStartCol, nStartColPos); + mnLOKStartHeaderCol = nStartCol; + } + + if (mnLOKEndHeaderCol != nEndCol) + { + rWidthHelper.removeByIndex(mnLOKEndHeaderCol); + rWidthHelper.insert(nEndCol, nEndColPos); + mnLOKEndHeaderCol = nEndCol; + } + + // Update mnLOKStartHeaderRow and mnLOKEndHeaderRow members. + // These are consulted in some ScGridWindow methods. + if (mnLOKStartHeaderRow != nStartRow) + { + rHeightHelper.removeByIndex(mnLOKStartHeaderRow); + rHeightHelper.insert(nStartRow, nStartRowPos); + mnLOKStartHeaderRow = nStartRow; + } + + if (mnLOKEndHeaderRow != nEndRow) + { + rHeightHelper.removeByIndex(mnLOKEndHeaderRow); + rHeightHelper.insert(nEndRow, nEndRowPos); + mnLOKEndHeaderRow = nEndRow; + } + + constexpr SCCOL nMinExtraCols = 10; + SCCOL nExtraCols = std::max<SCCOL>(nMinExtraCols, nEndCol - nStartCol); + // If we are approaching current max tiled column, signal a size changed event + // and invalidate the involved area. + lcl_ExtendTiledDimension(/* bColumn */ true, nEndCol, nExtraCols, *this, aViewData); + + constexpr SCROW nMinExtraRows = 25; + SCROW nExtraRows = std::max(nMinExtraRows, nEndRow - nStartRow); + // If we are approaching current max tiled row, signal a size changed event + // and invalidate the involved area. + lcl_ExtendTiledDimension(/* bColumn */ false, nEndRow, nExtraRows, *this, aViewData); + + vcl::Region aNewVisCellRange( + tools::Rectangle(mnLOKStartHeaderCol + 1, mnLOKStartHeaderRow + 1, + mnLOKEndHeaderCol, mnLOKEndHeaderRow)); + aNewVisCellRange.Exclude(aOldVisCellRange); + tools::Rectangle aChangedCellRange = aNewVisCellRange.GetBoundRect(); + if (!aChangedCellRange.IsEmpty()) + { + UpdateVisibleRange(); + UpdateFormulas(aChangedCellRange.Left(), aChangedCellRange.Top(), + aChangedCellRange.Right(), aChangedCellRange.Bottom()); + } + + SAL_INFO("sc.lok.header", + "extendTiledAreaIfNeeded: END: ClientView: ColRange[" + << mnLOKStartHeaderCol << "," << mnLOKEndHeaderCol + << "] RowRange[" << mnLOKStartHeaderRow << "," << mnLOKEndHeaderRow + << "] MaxTiledCol = " << aViewData.GetMaxTiledCol() + << " MaxTiledRow = " << aViewData.GetMaxTiledRow()); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |