tdf#154271 Fix automatic cursor/screen jump in Calc

Previously, when using ctrl+end, the screen/cursor jump was done to the
middle of the screen. In this way, the available space of the screen was
not optimally used.

In this patch, the jump is adjusted to move the cursor to the end of the
screen, and the visible/usable space will be all of the screen.

In this patch, previous behavior for showing the search results and
other purposes other than pressing ctrl+end to jump to the last cell are
preserved, and in those cases, the selected cell will be in the middle
of the screen, as before.

Also, in the situations that the jump is done from a cell lower or right
of the last cell (in other words, further than the last cell), the
behavior is preserved.

Change-Id: I25f308f84f096ec271c23df75998ddeea32119ea
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156266
Tested-by: Jenkins
Reviewed-by: Hossein <hossein@libreoffice.org>
diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
index 34bc8c4..5dd60f6 100644
--- a/sc/source/ui/inc/viewdata.hxx
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -49,7 +49,7 @@ inline ScHSplitPos WhichH( ScSplitPos ePos );
inline ScVSplitPos WhichV( ScSplitPos ePos );

/**  Screen behavior related to cursor movements */
enum ScFollowMode { SC_FOLLOW_NONE, SC_FOLLOW_LINE, SC_FOLLOW_FIX, SC_FOLLOW_JUMP };
enum ScFollowMode { SC_FOLLOW_NONE, SC_FOLLOW_LINE, SC_FOLLOW_FIX, SC_FOLLOW_JUMP, SC_FOLLOW_JUMP_END };

/** Mouse mode to select areas */
enum ScRefType { SC_REFTYPE_NONE, SC_REFTYPE_REF, SC_REFTYPE_FILL,
diff --git a/sc/source/ui/view/cellsh4.cxx b/sc/source/ui/view/cellsh4.cxx
index 8cf13970bd..bacbf2b 100644
--- a/sc/source/ui/view/cellsh4.cxx
+++ b/sc/source/ui/view/cellsh4.cxx
@@ -507,7 +507,7 @@ void ScCellShell::ExecutePage( SfxRequest& rReq )
            break;

        case SID_CURSORENDOFFILE:
            pTabViewShell->MoveCursorEnd( 1, 1, SC_FOLLOW_JUMP, bSel, bKeep );
            pTabViewShell->MoveCursorEnd( 1, 1, SC_FOLLOW_JUMP_END, bSel, bKeep );
            break;

        default:
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 9a321f7..723f2b4 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -959,8 +959,17 @@ void ScTabView::AlignToCursor( SCCOL nCurX, SCROW nCurY, ScFollowMode eMode,
        else
            nCellSizeX = nCellSizeY = 0;
        Size aScrSize = aViewData.GetScrSize();
        tools::Long nSpaceX = ( aScrSize.Width()  - nCellSizeX ) / 2;
        tools::Long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;

        tools::Long nDenom;
        if ( eMode == SC_FOLLOW_JUMP_END && nCurX > aViewData.GetRefStartX()
            && nCurY > aViewData.GetRefStartY() )
            nDenom = 1; // tdf#154271 Selected cell will be at the bottom corner
                        // to maximize the visible/usable area
        else
            nDenom = 2; // Selected cell will be at the center of the screen, so that
                        // it will be visible. This is useful for search results, etc.
        tools::Long nSpaceX = ( aScrSize.Width()  - nCellSizeX ) / nDenom;
        tools::Long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / nDenom;
        //  nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes

        bool bForceNew = false;     // force new calculation of JUMP position (vertical only)
@@ -971,7 +980,7 @@ void ScTabView::AlignToCursor( SCCOL nCurX, SCROW nCurY, ScFollowMode eMode,
        // if possible, put the row with the cursor above or below the dialog
        //! not if already completely visible

        if ( eMode == SC_FOLLOW_JUMP )
        if ( eMode == SC_FOLLOW_JUMP || eMode == SC_FOLLOW_JUMP_END )
        {
            weld::Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
            if (pCare)
@@ -1042,6 +1051,7 @@ void ScTabView::AlignToCursor( SCCOL nCurX, SCROW nCurY, ScFollowMode eMode,
        switch (eMode)
        {
            case SC_FOLLOW_JUMP:
            case SC_FOLLOW_JUMP_END:
                if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
                {
                    nNewDeltaX = nCurX - aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<sal_uInt16>(nSpaceX) );
@@ -1521,7 +1531,7 @@ bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
    if( (nCode == KEY_HOME) || (nCode == KEY_END) )
    {
        nDX = (nCode == KEY_HOME) ? -1 : 1;
        ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
        ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP_END;
        switch( eModifier )
        {
            case MOD_NONE:  MoveCursorEnd( nDX, 0, eMode, bSel );   break;