sc/source/ui/inc/viewdata.hxx  |    8 +++++---
 sc/source/ui/view/tabview.cxx  |    8 ++++----
 sc/source/ui/view/tabview2.cxx |    2 +-
 sc/source/ui/view/tabview3.cxx |    4 ++--
 sc/source/ui/view/viewdata.cxx |   14 ++++++++------
 5 files changed, 20 insertions(+), 16 deletions(-)

New commits:
commit bfa9d2aacd5188761cbde343748b5f6cd2c12583
Author:     Marco Cecchetti <marco.cecche...@collabora.com>
AuthorDate: Sun Jun 22 18:24:36 2025 +0200
Commit:     Marco Cecchetti <marco.cecche...@collabora.com>
CommitDate: Tue Jun 24 19:04:40 2025 +0200

    lok: CellsAtX, CellsAtY can return wrong values
    
    In lok case the document on the core side is never scrolled, so the
    document position is always the top of the document (that is (0,0))
    That means that the screen width and height can be greater than
    sal_uInt16 max value.
    So, in order to avoid unexpected truncation we need to use tools::Long
    in place of sal_uInt16.
    In fact before this patch we missed to report the correct CellsAtY value
    for cells below row 10000 and the correct CellsAtX value for cells
    beyond column AZZ.
    On cell editing that caused edit area width or height to be not expanded
    properly.
    
    Change-Id: I9f38b55ee9b1edbf9b5f0717155597f363bf9768
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186799
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
index 7c79bb91d65f..6b9dd8548ef7 100644
--- a/sc/source/ui/inc/viewdata.hxx
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -28,7 +28,7 @@
 #include <memory>
 #include <o3tl/typed_flags_set.hxx>
 
-#define SC_SIZE_NONE        65535
+constexpr auto SC_SIZE_NONE = std::numeric_limits<tools::Long>::max();
 
 enum class ScFillMode
 {
@@ -634,8 +634,10 @@ public:
     OString         describeCellCursorInPrintTwips() const { return 
describeCellCursorAt(GetCurX(), GetCurY(), false); }
     OString         describeCellCursorAt( SCCOL nCol, SCROW nRow, bool 
bPixelAligned = true ) const;
 
-    SCCOL           CellsAtX( SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX, 
sal_uInt16 nScrSizeY = SC_SIZE_NONE ) const;
-    SCROW           CellsAtY( SCROW nPosY, SCROW nDir, ScVSplitPos eWhichY, 
sal_uInt16 nScrSizeX = SC_SIZE_NONE ) const;
+    SCCOL           CellsAtX( SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX,
+                              tools::Long nScrSizeY = SC_SIZE_NONE ) const;
+    SCROW           CellsAtY( SCROW nPosY, SCROW nDir, ScVSplitPos eWhichY,
+                              tools::Long nScrSizeX = SC_SIZE_NONE ) const;
 
     SCCOL           VisibleCellsX( ScHSplitPos eWhichX ) const;     // 
Completely visible cell
     SCROW           VisibleCellsY( ScVSplitPos eWhichY ) const;
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 681cb2ebb724..61ff00bf5248 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -1776,8 +1776,8 @@ void ScTabView::DoHSplit(tools::Long nSplitPos)
         SCCOL nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
         tools::Long nLeftWidth = nSplitPos - 
pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
         if ( nLeftWidth < 0 ) nLeftWidth = 0;
-        SCCOL nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, 
SC_SPLIT_LEFT,
-                        static_cast<sal_uInt16>(nLeftWidth) );
+        SCCOL nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, 
SC_SPLIT_LEFT, nLeftWidth );
+
         ScDocument& rDoc = aViewData.GetDocument();
         if ( nNewDelta > rDoc.MaxCol() )
             nNewDelta = rDoc.MaxCol();
@@ -1849,8 +1849,8 @@ void ScTabView::DoVSplit(tools::Long nSplitPos)
         aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
         tools::Long nTopHeight = nSplitPos - 
pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
         if ( nTopHeight < 0 ) nTopHeight = 0;
-        SCROW nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, 
SC_SPLIT_TOP,
-                        static_cast<sal_uInt16>(nTopHeight) );
+        SCROW nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, 
SC_SPLIT_TOP, nTopHeight );
+
         ScDocument& rDoc = aViewData.GetDocument();
         if ( nNewDelta > rDoc.MaxRow() )
             nNewDelta = rDoc.MaxRow();
diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx
index 7f78e9575e83..7049ecdbca8d 100644
--- a/sc/source/ui/view/tabview2.cxx
+++ b/sc/source/ui/view/tabview2.cxx
@@ -797,7 +797,7 @@ void ScTabView::GetPageMoveEndPosition(SCCOL nMovX, SCROW 
nMovY, SCCOL& rPageX,
     ScHSplitPos eWhichX = WhichH( eWhich );
     ScVSplitPos eWhichY = WhichV( eWhich );
 
-    sal_uInt16 nScrSizeY = SC_SIZE_NONE;
+    auto nScrSizeY = SC_SIZE_NONE;
     if (comphelper::LibreOfficeKit::isActive() && 
aViewData.GetPageUpDownOffset() > 0) {
         nScrSizeY = ScViewData::ToPixel( aViewData.GetPageUpDownOffset(), 
aViewData.GetPPTX() );
     }
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index c322786de7fa..24a259871603 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -1085,14 +1085,14 @@ void ScTabView::AlignToCursor( SCCOL nCurX, SCROW 
nCurY, ScFollowMode eMode,
             case SC_FOLLOW_JUMP_END:
                 if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
                 {
-                    nNewDeltaX = nCurX - aViewData.CellsAtX( nCurX, -1, 
eAlignX, static_cast<sal_uInt16>(nSpaceX) );
+                    nNewDeltaX = nCurX - aViewData.CellsAtX( nCurX, -1, 
eAlignX, nSpaceX );
                     if (nNewDeltaX < 0)
                         nNewDeltaX = 0;
                     nSizeX = aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
                 }
                 if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
                 {
-                    nNewDeltaY = nCurY - aViewData.CellsAtY( nCurY, -1, 
eAlignY, static_cast<sal_uInt16>(nSpaceY) );
+                    nNewDeltaY = nCurY - aViewData.CellsAtY( nCurY, -1, 
eAlignY, nSpaceY );
                     if (nNewDeltaY < 0)
                         nNewDeltaY = 0;
                     nSizeY = aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index aac850ca7609..08f9c099e856 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -2687,16 +2687,17 @@ OString ScViewData::describeCellCursorAt(SCCOL nX, 
SCROW nY, bool bPixelAligned)
 }
 
 //      Number of cells on a screen
-SCCOL ScViewData::CellsAtX( SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX, 
sal_uInt16 nScrSizeX ) const
+SCCOL ScViewData::CellsAtX( SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX, 
tools::Long nScrSizeX ) const
 {
     OSL_ENSURE( nDir==1 || nDir==-1, "wrong CellsAt call" );
+    OSL_ENSURE(nScrSizeX >= 0, "ScViewData::CellsAtX: negative screen width");
 
     if (pView)
         const_cast<ScViewData*>(this)->aScrSize.setWidth( 
pView->GetGridWidth(eWhichX) );
 
     SCCOL  nX;
-    sal_uInt16  nScrPosX = 0;
-    if (nScrSizeX == SC_SIZE_NONE) nScrSizeX = 
static_cast<sal_uInt16>(aScrSize.Width());
+    tools::Long  nScrPosX = 0;
+    if (nScrSizeX == SC_SIZE_NONE) nScrSizeX = aScrSize.Width();
 
     if (nDir==1)
         nX = nPosX;             // forwards
@@ -2715,7 +2716,7 @@ SCCOL ScViewData::CellsAtX( SCCOL nPosX, SCCOL nDir, 
ScHSplitPos eWhichX, sal_uI
             if (nTSize)
             {
                 tools::Long nSizeXPix = ToPixel( nTSize, nPPTX );
-                nScrPosX = sal::static_int_cast<sal_uInt16>( nScrPosX + 
static_cast<sal_uInt16>(nSizeXPix) );
+                nScrPosX = nScrPosX + nSizeXPix;
             }
         }
     }
@@ -2729,14 +2730,15 @@ SCCOL ScViewData::CellsAtX( SCCOL nPosX, SCCOL nDir, 
ScHSplitPos eWhichX, sal_uI
     return nX;
 }
 
-SCROW ScViewData::CellsAtY( SCROW nPosY, SCROW nDir, ScVSplitPos eWhichY, 
sal_uInt16 nScrSizeY ) const
+SCROW ScViewData::CellsAtY( SCROW nPosY, SCROW nDir, ScVSplitPos eWhichY, 
tools::Long nScrSizeY ) const
 {
     OSL_ENSURE( nDir==1 || nDir==-1, "wrong CellsAt call" );
+    OSL_ENSURE(nScrSizeY >= 0, "ScViewData::CellsAtY: negative screen height");
 
     if (pView)
         const_cast<ScViewData*>(this)->aScrSize.setHeight( 
pView->GetGridHeight(eWhichY) );
 
-    if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = 
static_cast<sal_uInt16>(aScrSize.Height());
+    if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = aScrSize.Height();
 
     SCROW nY;
 

Reply via email to