sw/inc/crsrsh.hxx                    |    8 ++++----
 sw/inc/fesh.hxx                      |    2 +-
 sw/inc/mdiexp.hxx                    |    4 +++-
 sw/inc/view.hxx                      |    7 +++++--
 sw/inc/viewsh.hxx                    |    9 ++++++++-
 sw/source/core/crsr/crsrsh.cxx       |   19 ++++++++++---------
 sw/source/core/frmedt/feshview.cxx   |    4 ++--
 sw/source/core/view/viewsh.cxx       |    4 ++--
 sw/source/ui/dialog/uiregionsw.cxx   |    2 +-
 sw/source/ui/index/swuiidxmrk.cxx    |    2 +-
 sw/source/ui/misc/insfnote.cxx       |    6 +++---
 sw/source/uibase/dochdl/swdtflvr.cxx |    2 +-
 sw/source/uibase/docvw/edtdd.cxx     |    4 ++--
 sw/source/uibase/docvw/edtwin.cxx    |   22 ++++++++++++++--------
 sw/source/uibase/docvw/edtwin3.cxx   |    5 +++--
 sw/source/uibase/inc/edtwin.hxx      |    4 +++-
 sw/source/uibase/inc/wrtsh.hxx       |   20 +++++++++++++-------
 sw/source/uibase/shells/tabsh.cxx    |    2 +-
 sw/source/uibase/shells/textsh1.cxx  |    2 +-
 sw/source/uibase/uiview/viewport.cxx |   29 +++++++++++++++++++++++------
 sw/source/uibase/uno/unotxdoc.cxx    |    2 +-
 sw/source/uibase/wrtsh/move.cxx      |    6 +++---
 sw/source/uibase/wrtsh/select.cxx    |   16 ++++++++--------
 sw/source/uibase/wrtsh/wrtsh3.cxx    |    8 ++++----
 24 files changed, 117 insertions(+), 72 deletions(-)

New commits:
commit 80d581202abf3fe0a1a565016182c756d27ec429
Author:     Oliver Specht <oliver.spe...@cib.de>
AuthorDate: Wed Dec 18 15:11:38 2024 +0100
Commit:     Gabor Kelemen <gabor.kelemen.ext...@allotropia.de>
CommitDate: Tue Feb 11 17:38:39 2025 +0100

    tdf#50743 tdf#37507 Improve scrolling while selecting
    
    If the mouse leaves the document window scrolling of selections
    happens now in smaller steps so the user is able to stop at the
    intended position easier.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178724
    Reviewed-by: Gabor Kelemen <gabor.kelemen.ext...@allotropia.de>
    Tested-by: Jenkins
    Tested-by: Gabor Kelemen <gabor.kelemen.ext...@allotropia.de>
    Change-Id: Ic6c48cffa246b0e341bc25c35070e95f5e706f0c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181415
    Tested-by: allotropia jenkins <jenk...@allotropia.de>

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 2417fb507cae..fd1ca6b11fa2 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -169,7 +169,7 @@ public:
 
     SW_DLLPUBLIC void UpdateCursor(
         sal_uInt16 eFlags = SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE,
-        bool bIdleEnd = false );
+        bool bIdleEnd = false, ScrollSizeMode eScrollSizeMode = 
ScrollSizeMode::ScrollSizeDefault );
 
 private:
 
@@ -421,7 +421,7 @@ public:
      *        the cursor is done in order to get at the properties under the 
mouse pointer.
      */
     SW_DLLPUBLIC int SetCursor(const Point& rPt, bool bOnlyText = false, bool 
bBlock = true,
-                  bool bFieldInfo = false);
+                  bool bFieldInfo = false, ScrollSizeMode eScrollSizeMode = 
ScrollSizeMode::ScrollSizeDefault);
 
     /*
      * Notification that the visible area was changed. m_aVisArea is reset, 
then
@@ -731,7 +731,7 @@ public:
     // Place only the visible cursor at the given position in the document.
     // Return false if SPoint was corrected by layout.
     // (This is needed for displaying the Drag&Drop/Copy-Cursor.)
-    bool SetVisibleCursor( const Point &rPt );
+    bool SetVisibleCursor( const Point &rPt, ScrollSizeMode eScrollSizeMode = 
ScrollSizeMode::ScrollSizeDefault );
     inline void UnSetVisibleCursor();
     SW_DLLPUBLIC SwVisibleCursor* GetVisibleCursor() const;
 
@@ -813,7 +813,7 @@ public:
     bool GotoRegion( std::u16string_view rName );
 
     // show the current selection
-    virtual void MakeSelVisible();
+    virtual void MakeSelVisible(ScrollSizeMode eScrollSizeMode = 
ScrollSizeMode::ScrollSizeDefault);
 
     // set the cursor to a NOT protected/hidden node
     bool FindValidContentNode( bool bOnlyText );
diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx
index 6e4466dc60d7..b6ccbee8b939 100644
--- a/sw/inc/fesh.hxx
+++ b/sw/inc/fesh.hxx
@@ -360,7 +360,7 @@ public:
     void SetPageObjsNewPage( std::vector<SwFrameFormat*>& rFillArr );
 
     /// Show current selection (frame / draw object as required).
-    virtual void MakeSelVisible() override;
+    virtual void MakeSelVisible(ScrollSizeMode eScrollSizeMode = 
ScrollSizeMode::ScrollSizeDefault) override;
 
     /** @return FrameFormat of object that may be under Point.
      Object does not become selected! */
diff --git a/sw/inc/mdiexp.hxx b/sw/inc/mdiexp.hxx
index afe308e1ad89..6d4af73bd80b 100644
--- a/sw/inc/mdiexp.hxx
+++ b/sw/inc/mdiexp.hxx
@@ -22,6 +22,7 @@
 #include "tblenum.hxx"
 #include "swdllapi.h"
 #include <unotools/resmgr.hxx>
+#include "viewsh.hxx"
 
 #include <string_view>
 
@@ -30,7 +31,8 @@ class Size;
 class SwViewShell;
 class SwDocShell;
 
-extern void ScrollMDI(SwViewShell const * pVwSh, const SwRect &, sal_uInt16 
nRangeX, sal_uInt16 nRangeY);
+extern void ScrollMDI(SwViewShell const * pVwSh, const SwRect &, sal_uInt16 
nRangeX, sal_uInt16 nRangeY
+    , ScrollSizeMode eScrollSizeMode = ScrollSizeMode::ScrollSizeDefault);
 extern bool IsScrollMDI(SwViewShell const * pVwSh, const SwRect &);
 extern void SizeNotify(SwViewShell const * pVwSh, const Size &);
 
diff --git a/sw/inc/view.hxx b/sw/inc/view.hxx
index d735e5e6e94a..6e7f0b4d2d05 100644
--- a/sw/inc/view.hxx
+++ b/sw/inc/view.hxx
@@ -31,6 +31,7 @@
 #include "swdllapi.h"
 #include "swtypes.hxx"
 #include "shellid.hxx"
+#include "viewsh.hxx"
 
 #include <svx/sdr/overlay/overlayobject.hxx>
 
@@ -299,7 +300,8 @@ class SW_DLLPUBLIC SwView: public SfxViewShell
     SAL_DLLPRIVATE Point         AlignToPixel(const Point& rPt) const;
     SAL_DLLPRIVATE void          CalcPt( Point* pPt,const tools::Rectangle& 
rRect,
                                     sal_uInt16 nRangeX,
-                                    sal_uInt16 nRangeY);
+                                    sal_uInt16 nRangeY,
+                                    ScrollSizeMode eScrollSizeMode);
 
     SAL_DLLPRIVATE bool          GetPageScrollUpOffset(SwTwips& rOff) const;
     SAL_DLLPRIVATE bool          GetPageScrollDownOffset(SwTwips& rOff) const;
@@ -444,7 +446,8 @@ public:
     bool            IsScroll(const tools::Rectangle& rRect) const;
     void            Scroll( const tools::Rectangle& rRect,
                             sal_uInt16 nRangeX = USHRT_MAX,
-                            sal_uInt16 nRangeY = USHRT_MAX);
+                            sal_uInt16 nRangeY = USHRT_MAX,
+                            ScrollSizeMode eScrollSizeMode = 
ScrollSizeMode::ScrollSizeDefault);
 
     tools::Long            SetVScrollMax(tools::Long lMax);
     tools::Long            SetHScrollMax(tools::Long lMax);
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 01a3cc259929..fd7c1e08a1fd 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -84,6 +84,13 @@ enum class LockPaintReason
     ExampleFrame
 };
 
+enum class ScrollSizeMode
+{
+    ScrollSizeDefault, //usually 30% of the visible area
+    ScrollSizeMouseSelection, //make target rectangle visible
+    ScrollSizeTimer, // increase of timer based scrolling
+    ScrollSizeTimer2 // more increase of timer based scrolling
+};
 namespace vcl
 {
     typedef OutputDevice RenderContext;
@@ -281,7 +288,7 @@ public:
     void setLOKVisibleArea(const tools::Rectangle& rArea) { maLOKVisibleArea = 
rArea; }
 
     // If necessary scroll until passed Rect is situated in visible sector.
-    void MakeVisible( const SwRect & );
+    void MakeVisible( const SwRect &, ScrollSizeMode eScrollSizeMode = 
ScrollSizeMode::ScrollSizeDefault );
 
     // At nearest occasion pass new document size to UI.
     void SizeChgNotify();
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index a092c19a6e68..1d65422ee0ae 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -1058,7 +1058,8 @@ bool SwCursorShell::IsInHeaderFooter( bool* pbInHeader ) 
const
     return nullptr != pFrame;
 }
 
-int SwCursorShell::SetCursor(const Point& rLPt, bool bOnlyText, bool bBlock, 
bool bFieldInfo)
+int SwCursorShell::SetCursor(const Point& rLPt, bool bOnlyText, bool bBlock,
+    bool bFieldInfo, ScrollSizeMode eScrollSizeMode)
 {
     CurrShell aCurr( this );
 
@@ -1163,7 +1164,7 @@ int SwCursorShell::SetCursor(const Point& rLPt, bool 
bOnlyText, bool bBlock, boo
 
     if( !pCursor->IsSelOvr( SwCursorSelOverFlags::ChangePos ) )
     {
-        UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE );
+        UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE, 
false, eScrollSizeMode );
         bRet &= ~CRSR_POSOLD;
     }
     else if( bOnlyText && !m_pCurrentCursor->HasMark() )
@@ -1921,7 +1922,7 @@ class SwNotifyAccAboutInvalidTextSelections
 }
 #endif
 
-void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd )
+void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd, 
ScrollSizeMode eScrollSizeMode )
 {
     CurrShell aCurr( this );
     ClearUpCursors();
@@ -2364,7 +2365,7 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool 
bIdleEnd )
             // again, thus save and reset the flag here
             bool bSav = m_bSVCursorVis;
             m_bSVCursorVis = false;
-            MakeSelVisible();
+            MakeSelVisible(eScrollSizeMode);
             m_bSVCursorVis = bSav;
         }
 
@@ -3053,7 +3054,7 @@ bool SwCursorShell::ExtendSelection( bool bEnd, sal_Int32 
nCount )
     @param rPt The position to move the visible cursor to.
     @return <false> if SPoint was corrected by the layout.
 */
-bool SwCursorShell::SetVisibleCursor( const Point &rPt )
+bool SwCursorShell::SetVisibleCursor( const Point &rPt, ScrollSizeMode 
eScrollSizeMode )
 {
     CurrShell aCurr( this );
     Point aPt( rPt );
@@ -3092,7 +3093,7 @@ bool SwCursorShell::SetVisibleCursor( const Point &rPt )
     m_pVisibleCursor->Hide(); // always hide visible cursor
     if( IsScrollMDI( this, m_aCharRect ))
     {
-        MakeVisible( m_aCharRect );
+        MakeVisible( m_aCharRect, eScrollSizeMode );
         m_pCurrentCursor->Show(nullptr);
     }
 
@@ -3478,7 +3479,7 @@ size_t SwCursorShell::UpdateTableSelBoxes()
 }
 
 /// show the current selected "object"
-void SwCursorShell::MakeSelVisible()
+void SwCursorShell::MakeSelVisible(ScrollSizeMode eScrollSizeMode)
 {
     OSL_ENSURE( m_bHasFocus, "no focus but cursor should be made visible?" );
     if( m_aCursorHeight.Y() < m_aCharRect.Height() && m_aCharRect.Height() > 
VisArea().Height() )
@@ -3502,13 +3503,13 @@ void SwCursorShell::MakeSelVisible()
     else
     {
         if( m_aCharRect.HasArea() )
-            MakeVisible( m_aCharRect );
+            MakeVisible( m_aCharRect, eScrollSizeMode );
         else
         {
             SwRect aTmp( m_aCharRect );
             aTmp.AddHeight(1 );
             aTmp.AddWidth(1 );
-            MakeVisible( aTmp );
+            MakeVisible( aTmp, eScrollSizeMode );
         }
     }
 }
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index 0a3830009e99..8bdc243762b0 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -2658,7 +2658,7 @@ std::vector<SwFrameFormat const*> 
SwFEShell::GetFlyFrameFormats(
 }
 
 // show the current selected object
-void SwFEShell::MakeSelVisible()
+void SwFEShell::MakeSelVisible(ScrollSizeMode eScrollSizeMode)
 {
     if ( Imp()->HasDrawView() &&
          Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )
@@ -2667,7 +2667,7 @@ void SwFEShell::MakeSelVisible()
         MakeVisible( SwRect(Imp()->GetDrawView()->GetAllMarkedRect()) );
     }
     else
-        SwCursorShell::MakeSelVisible();
+        SwCursorShell::MakeSelVisible(eScrollSizeMode);
 }
 
 // how is the selected object protected?
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index c4d9a551807c..00e84594dab5 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -646,7 +646,7 @@ const SwRect& SwViewShell::VisArea() const
     return comphelper::LibreOfficeKit::isActive()? 
GetLayout()->getFrameArea(): maVisArea;
 }
 
-void SwViewShell::MakeVisible( const SwRect &rRect )
+void SwViewShell::MakeVisible( const SwRect &rRect, ScrollSizeMode 
eScrollSizeMode )
 {
     if ( !(!VisArea().Contains( rRect ) || IsScrollMDI( this, rRect ) || 
GetCareDialog(*this)) )
         return;
@@ -662,7 +662,7 @@ void SwViewShell::MakeVisible( const SwRect &rRect )
         do{
             nOldH = pRoot->getFrameArea().Height();
             StartAction();
-            ScrollMDI( this, rRect, USHRT_MAX, USHRT_MAX );
+            ScrollMDI( this, rRect, USHRT_MAX, USHRT_MAX, eScrollSizeMode );
             EndAction();
         } while( nOldH != pRoot->getFrameArea().Height() && nLoopCnt-- );
     }
diff --git a/sw/source/ui/dialog/uiregionsw.cxx 
b/sw/source/ui/dialog/uiregionsw.cxx
index f1499b6a28ca..58f9e4012feb 100644
--- a/sw/source/ui/dialog/uiregionsw.cxx
+++ b/sw/source/ui/dialog/uiregionsw.cxx
@@ -764,7 +764,7 @@ IMPL_LINK_NOARG(SwEditRegionDlg, OkHdl, weld::Button&, void)
 
     m_rSh.StartAllAction();
     m_rSh.StartUndo();
-    m_rSh.ResetSelect( nullptr,false );
+    m_rSh.ResetSelect( nullptr,false, ScrollSizeMode::ScrollSizeDefault );
 
     std::unique_ptr<weld::TreeIter> xIter(m_xTree->make_iterator());
     if (m_xTree->get_iter_first(*xIter))
diff --git a/sw/source/ui/index/swuiidxmrk.cxx 
b/sw/source/ui/index/swuiidxmrk.cxx
index 0d30104f9e41..242439606e5e 100644
--- a/sw/source/ui/index/swuiidxmrk.cxx
+++ b/sw/source/ui/index/swuiidxmrk.cxx
@@ -453,7 +453,7 @@ void SwIndexMarkPane::Apply()
 {
     InsertUpdate();
     if(m_bSelected)
-        m_pSh->ResetSelect(nullptr, false);
+        m_pSh->ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
 }
 
 // apply changes
diff --git a/sw/source/ui/misc/insfnote.cxx b/sw/source/ui/misc/insfnote.cxx
index 4ddc4c1f9117..22ea93ad5bc6 100644
--- a/sw/source/ui/misc/insfnote.cxx
+++ b/sw/source/ui/misc/insfnote.cxx
@@ -58,7 +58,7 @@ void SwInsFootNoteDlg::Apply()
                                m_eCharSet, RES_CHRATR_FONT );
             aSet.Put( aFont );
             m_rSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND );
-            m_rSh.ResetSelect(nullptr, false);
+            m_rSh.ResetSelect(nullptr, false, 
ScrollSizeMode::ScrollSizeDefault);
             m_rSh.Left(SwCursorSkipMode::Chars, false, 1, false );
         }
         m_rSh.EndUndo( SwUndoId::END );
@@ -138,7 +138,7 @@ IMPL_LINK( SwInsFootNoteDlg, NextPrevHdl, weld::Button&, 
rBtn, void )
     Apply();
 
     // go to the next foot/endnote here
-    m_rSh.ResetSelect(nullptr, false);
+    m_rSh.ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
     if (&rBtn == m_xNextBT.get())
         m_rSh.GotoNextFootnoteAnchor();
     else
@@ -188,7 +188,7 @@ SwInsFootNoteDlg::~SwInsFootNoteDlg() 
COVERITY_NOEXCEPT_FALSE
     SwViewShell::SetCareDialog(nullptr);
 
     if (m_bEdit)
-        m_rSh.ResetSelect(nullptr, false);
+        m_rSh.ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
 }
 
 void SwInsFootNoteDlg::Init()
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx 
b/sw/source/uibase/dochdl/swdtflvr.cxx
index 0ec3b35e86b9..84ae65d18c8a 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -3878,7 +3878,7 @@ bool SwTransferable::PrivatePaste(SwWrtShell& rShell, 
SwPasteContext* pContext,
     }
     if ( nSelection & SelectionType::DrawObject) //unselect hovering graphics
     {
-        rShell.ResetSelect(nullptr,false);
+        rShell.ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
     }
 
     bool bInWrd = false, bEndWrd = false, bSttWrd = false,
diff --git a/sw/source/uibase/docvw/edtdd.cxx b/sw/source/uibase/docvw/edtdd.cxx
index 287d2969f632..45dd6d8439f4 100644
--- a/sw/source/uibase/docvw/edtdd.cxx
+++ b/sw/source/uibase/docvw/edtdd.cxx
@@ -371,7 +371,7 @@ sal_Int8 SwEditWin::AcceptDrop( const AcceptDropEvent& rEvt 
)
             if(aPixPt.Y() < aWin.Top()) aPixPt.AdjustY( -nMargin );
             Point aDocPt(PixelToLogic(aPixPt));
             SwRect rect(aDocPt,Size(1,1));
-            rSh.MakeVisible(rect);
+            rSh.MakeVisible(rect, ScrollSizeMode::ScrollSizeTimer2);
         }
     }
 
@@ -461,7 +461,7 @@ sal_Int8 SwEditWin::AcceptDrop( const AcceptDropEvent& rEvt 
)
             CleanupDropUserMarker();
             SwContentAtPos aCont( IsAttrAtPos::ContentCheck );
             if(rSh.GetContentAtPos(aDocPt, aCont))
-                rSh.SwCursorShell::SetVisibleCursor( aDocPt );
+                rSh.SwCursorShell::SetVisibleCursor( aDocPt, 
ScrollSizeMode::ScrollSizeMouseSelection );
         }
         else
         {
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index f60cfd1607a5..6893aea25a04 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -679,7 +679,7 @@ IMPL_LINK_NOARG(SwEditWin, TimerHandler, Timer *, void)
             rSh.SelectTableRowCol( *m_xRowColumnSelectionStart, &aPos, 
m_bIsRowDrag );
         }
         else
-            rSh.CallSetCursor( &aModPt, false );
+            rSh.CallSetCursor( &aModPt, false, m_eScrollSizeMode );
 
         // It can be that a "jump" over a table cannot be accomplished like
         // that. So we jump over the table by Up/Down here.
@@ -703,15 +703,20 @@ void SwEditWin::JustifyAreaTimer()
 {
     const tools::Rectangle &rVisArea = GetView().GetVisArea();
 #ifdef UNX
-    const tools::Long coMinLen = 100;
+    const tools::Long coMinLen = 40;
 #else
-    const tools::Long coMinLen = 50;
+    const tools::Long coMinLen = 20;
 #endif
     tools::Long const nTimeout = 800,
          nDiff = std::max(
          std::max( m_aMovePos.Y() - rVisArea.Bottom(), rVisArea.Top() - 
m_aMovePos.Y() ),
          std::max( m_aMovePos.X() - rVisArea.Right(),  rVisArea.Left() - 
m_aMovePos.X()));
-    m_aTimer.SetTimeout( std::max( coMinLen, nTimeout - nDiff*2L) );
+    m_aTimer.SetTimeout( std::max( coMinLen, nTimeout - nDiff) );
+    m_eScrollSizeMode = m_aTimer.GetTimeout() < 100 ?
+        ScrollSizeMode::ScrollSizeTimer2 :
+        m_aTimer.GetTimeout() < 400 ?
+            ScrollSizeMode::ScrollSizeTimer :
+            ScrollSizeMode::ScrollSizeMouseSelection;
 }
 
 void SwEditWin::LeaveArea(const Point &rPos)
@@ -3953,7 +3958,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
 
                 if ( !bOverSelect || rSh.IsInSelect() )
                 {
-                    MoveCursor( rSh, aDocPos, bOnlyText, bLockView );
+                    MoveCursor( rSh, aDocPos, bOnlyText, bLockView);
                     bCallBase = false;
                 }
                 if (!bOverURLGrf && !bExecDrawTextLink && !bOnlyText)
@@ -4537,8 +4542,8 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
                           rSh.IsAddMode() ) )
                     {
                         rSh.Drag( &aDocPt, false );
-
-                        g_bValidCursorPos = !(CRSR_POSCHG & 
rSh.CallSetCursor(&aDocPt, false));
+                        g_bValidCursorPos = !(CRSR_POSCHG & 
rSh.CallSetCursor(&aDocPt, false,
+                            ScrollSizeMode::ScrollSizeMouseSelection));
                         EnterArea();
                     }
                 }
@@ -5455,6 +5460,7 @@ SwEditWin::SwEditWin(vcl::Window *pParent, SwView 
&rMyView):
     m_aTimer("SwEditWin"),
     m_aKeyInputFlushTimer("SwEditWin m_aKeyInputFlushTimer"),
     m_eBufferLanguage(LANGUAGE_DONTKNOW),
+    m_eScrollSizeMode(ScrollSizeMode::ScrollSizeMouseSelection),
     m_aTemplateTimer("SwEditWin m_aTemplateTimer"),
     m_pUserMarkerObj( nullptr ),
 
@@ -6257,7 +6263,7 @@ void SwEditWin::SelectMenuPosition(SwWrtShell& rSh, const 
Point& rMousePos )
         // the query against the content form doesn't work!!!
         SwMvContext aMvContext( &rSh );
         if (rSh.HasSelection())
-            rSh.ResetSelect(&aDocPos, false);
+            rSh.ResetSelect(&aDocPos, false, 
ScrollSizeMode::ScrollSizeDefault);
         rSh.SwCursorShell::SetCursor(aDocPos, false, /*Block=*/false, 
/*FieldInfo=*/true);
     }
     if( !bOverURLGrf )
diff --git a/sw/source/uibase/docvw/edtwin3.cxx 
b/sw/source/uibase/docvw/edtwin3.cxx
index 423b6a53847e..3eea118d5b42 100644
--- a/sw/source/uibase/docvw/edtwin3.cxx
+++ b/sw/source/uibase/docvw/edtwin3.cxx
@@ -33,12 +33,13 @@
 
 // Core-Notify
 void ScrollMDI( SwViewShell const * pVwSh, const SwRect &rRect,
-                sal_uInt16 nRangeX, sal_uInt16 nRangeY)
+                sal_uInt16 nRangeX, sal_uInt16 nRangeY,
+                ScrollSizeMode eScrollSizeMode)
 {
     SfxViewShell *pSfxViewShell = pVwSh->GetSfxViewShell();
 
     if (SwView* pSwView = dynamic_cast<SwView *>(pSfxViewShell))
-        pSwView->Scroll(rRect.SVRect(), nRangeX, nRangeY);
+        pSwView->Scroll(rRect.SVRect(), nRangeX, nRangeY, eScrollSizeMode);
 }
 
 // Docmdi - movable
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index ac6bbaeeeeff..ddce03274402 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -28,6 +28,7 @@
 #include <vcl/transfer.hxx>
 #include <swevent.hxx>
 #include <swtypes.hxx>
+#include <viewsh.hxx>
 
 class   SwWrtShell;
 class   SwView;
@@ -81,6 +82,7 @@ class SAL_DLLPUBLIC_RTTI SwEditWin final : public 
vcl::DocWindow,
     LanguageType    m_eBufferLanguage;
     Point           m_aStartPos;
     Point           m_aMovePos;
+    ScrollSizeMode  m_eScrollSizeMode;
     Point           m_aRszMvHdlPt;
     Timer           m_aTemplateTimer;
 
@@ -171,7 +173,7 @@ class SAL_DLLPUBLIC_RTTI SwEditWin final : public 
vcl::DocWindow,
     DECL_LINK( TemplateTimerHdl, Timer *, void );
 
     void            MoveCursor( SwWrtShell &rSh, const Point& rDocPos,
-                                const bool bOnlyText, bool bLockView );
+                                const bool bOnlyText, bool bLockView);
 
     virtual void    DataChanged( const DataChangedEvent& ) override;
     virtual void    PrePaint(vcl::RenderContext& rRenderContext) override;
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 06f833040948..8e644a9952da 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -108,7 +108,7 @@ private:
     using SwEditShell::AutoCorrect;
     using SwCursorShell::GotoMark;
 
-    typedef tools::Long (SwWrtShell::*SELECTFUNC)(const Point *, bool bProp );
+    typedef tools::Long (SwWrtShell::*SELECTFUNC)(const Point *, bool bProp, 
ScrollSizeMode eScrollSizeMode );
     typedef void (SwWrtShell::*SELECTFUNC2)(const Point *, bool bProp );
 
     SELECTFUNC2 m_fnDrag      = &SwWrtShell::BeginDrag;
@@ -120,16 +120,20 @@ public:
     using SwCursorShell::GotoFootnoteAnchor;
     using SwEditShell::Insert;
 
-    tools::Long CallSetCursor(const Point* pPt, bool bProp) { return 
(this->*m_fnSetCursor)(pPt, bProp); }
+    tools::Long CallSetCursor(const Point* pPt, bool bProp,
+        ScrollSizeMode eScrollSizeMode = ScrollSizeMode::ScrollSizeDefault)
+        { return (this->*m_fnSetCursor)(pPt, bProp, eScrollSizeMode); }
     void Drag         (const Point* pPt, bool bProp) { (this->*m_fnDrag)(pPt, 
bProp); }
     void EndDrag      (const Point* pPt, bool bProp) { 
(this->*m_fnEndDrag)(pPt, bProp); }
-    tools::Long KillSelection(const Point* pPt, bool bProp) { return 
(this->*m_fnKillSel)(pPt, bProp); }
+    tools::Long KillSelection(const Point* pPt, bool bProp,
+        ScrollSizeMode eScrollSizeMode = ScrollSizeMode::ScrollSizeDefault)
+        { return (this->*m_fnKillSel)(pPt, bProp, eScrollSizeMode ); }
 
     bool IsSplitVerticalByDefault() const;
     void SetSplitVerticalByDefault(bool value);
 
     // reset all selections
-    SW_DLLPUBLIC tools::Long ResetSelect( const Point *, bool );
+    SW_DLLPUBLIC tools::Long ResetSelect( const Point *, bool, ScrollSizeMode 
);
 
     // resets the cursorstack after movement with PageUp/-Down if a stack is 
built up
     inline void ResetCursorStack();
@@ -615,9 +619,11 @@ private:
     void  ResetCursorStack_();
 
     using SwCursorShell::SetCursor;
-    tools::Long  SetCursor(const Point *, bool bProp=false );
+    tools::Long  SetCursor(const Point *, bool bProp=false,
+        ScrollSizeMode eScrollSizeMode = ScrollSizeMode::ScrollSizeDefault );
 
-    tools::Long  SetCursorKillSel(const Point *, bool bProp );
+    tools::Long  SetCursorKillSel(const Point *, bool bProp,
+        ScrollSizeMode eScrollSizeMode = ScrollSizeMode::ScrollSizeDefault );
 
     void  BeginDrag(const Point *, bool bProp );
     void  DefaultDrag(const Point *, bool bProp );
@@ -633,7 +639,7 @@ private:
 
     void  SttLeaveSelect();
     void  AddLeaveSelect();
-    tools::Long  Ignore(const Point *, bool bProp );
+    tools::Long  Ignore(const Point *, bool bProp, ScrollSizeMode 
eScrollSizeMode = ScrollSizeMode::ScrollSizeDefault );
 
     void  LeaveExtSel() { m_bSelWrd = m_bSelLn = false;}
 
diff --git a/sw/source/uibase/shells/tabsh.cxx 
b/sw/source/uibase/shells/tabsh.cxx
index 2fa9db78f6cb..308123877c57 100644
--- a/sw/source/uibase/shells/tabsh.cxx
+++ b/sw/source/uibase/shells/tabsh.cxx
@@ -862,7 +862,7 @@ void SwTableShell::Execute(SfxRequest &rReq)
             break;
         case FN_TABLE_SET_READ_ONLY_CELLS:
             rSh.ProtectCells();
-            rSh.ResetSelect( nullptr, false );
+            rSh.ResetSelect( nullptr, false, ScrollSizeMode::ScrollSizeDefault 
);
             bCallDone = true;
             break;
         case FN_TABLE_UNSET_READ_ONLY_CELLS:
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index 5afb496f60e8..5e47d67abdfd 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -979,7 +979,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
                 SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT> aSet( 
rWrtSh.GetAttrPool() );
                 rWrtSh.GetCurAttr( aSet );
                 rWrtSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND );
-                rWrtSh.ResetSelect(nullptr, false);
+                rWrtSh.ResetSelect(nullptr, false, 
ScrollSizeMode::ScrollSizeDefault);
                 rWrtSh.EndSelect();
                 rWrtSh.GotoFootnoteText();
             }
diff --git a/sw/source/uibase/uiview/viewport.cxx 
b/sw/source/uibase/uiview/viewport.cxx
index a7ec3f161b60..252b0aa34122 100644
--- a/sw/source/uibase/uiview/viewport.cxx
+++ b/sw/source/uibase/uiview/viewport.cxx
@@ -339,14 +339,29 @@ void SwView::CheckVisArea()
 //                              within the new visible area.
 //  sal_uInt16 nRange           optional accurate indication of the
 //                              range by which to scroll if necessary.
+//  eScrollSizeMode             mouse selection should only bring the selected 
part
+//                              into the visible area, timer call needs 
increased size
 
-void SwView::CalcPt( Point *pPt, const tools::Rectangle &rRect,
-                     sal_uInt16 nRangeX, sal_uInt16 nRangeY)
+void SwView::CalcPt( Point *pPt, const tools::Rectangle &rRect, sal_uInt16 
nRangeX,
+                    sal_uInt16 nRangeY, ScrollSizeMode eScrollSizeMode)
 {
 
     const SwTwips lMin = IsDocumentBorder() ? DOCUMENTBORDER : 0;
 
-    tools::Long nYScroll = GetYScroll();
+    const tools::Long nDefaultYScroll = GetYScroll();
+    tools::Long nYScroll;
+    if (eScrollSizeMode != ScrollSizeMode::ScrollSizeDefault)
+    {
+        nYScroll = m_aVisArea.Top() > rRect.Top() ?
+            m_aVisArea.Top() - rRect.Top() :
+            rRect.Bottom() - m_aVisArea.Bottom();
+        if (eScrollSizeMode == ScrollSizeMode::ScrollSizeTimer)
+             nYScroll = std::min(nDefaultYScroll, nYScroll * 5);
+        else if (eScrollSizeMode == ScrollSizeMode::ScrollSizeTimer2)
+             nYScroll = 2 * nDefaultYScroll;
+    }
+    else
+        nYScroll = nDefaultYScroll;
     tools::Long nDesHeight = rRect.GetHeight();
     tools::Long nCurHeight = m_aVisArea.GetHeight();
     nYScroll = std::min(nYScroll, nCurHeight - nDesHeight); // If it is 
scarce, then scroll not too much.
@@ -391,7 +406,8 @@ bool SwView::IsScroll( const tools::Rectangle &rRect ) const
     return m_bCenterCursor || m_bTopCursor || !m_aVisArea.Contains(rRect);
 }
 
-void SwView::Scroll( const tools::Rectangle &rRect, sal_uInt16 nRangeX, 
sal_uInt16 nRangeY )
+void SwView::Scroll( const tools::Rectangle &rRect, sal_uInt16 nRangeX, 
sal_uInt16 nRangeY
+    , ScrollSizeMode eScrollSizeMode )
 {
     if ( m_aVisArea.IsEmpty() )
         return;
@@ -463,7 +479,8 @@ void SwView::Scroll( const tools::Rectangle &rRect, 
sal_uInt16 nRangeX, sal_uInt
 
         CalcPt( &aPt, tools::Rectangle( rRect.TopLeft(), aSize ),
                 static_cast< sal_uInt16 >((aVisSize.Width() - aSize.Width()) / 
2),
-                static_cast< sal_uInt16 >((aVisSize.Height()- aSize.Height())/ 
2) );
+                static_cast< sal_uInt16 >((aVisSize.Height()- aSize.Height())/ 
2),
+                eScrollSizeMode );
 
         if( m_bTopCursor )
         {
@@ -480,7 +497,7 @@ void SwView::Scroll( const tools::Rectangle &rRect, 
sal_uInt16 nRangeX, sal_uInt
     if( !m_bCenterCursor )
     {
         Point aPt( m_aVisArea.TopLeft() );
-        CalcPt( &aPt, rRect, nRangeX, nRangeY );
+        CalcPt( &aPt, rRect, nRangeX, nRangeY, eScrollSizeMode );
 
         if( m_bTopCursor )
         {
diff --git a/sw/source/uibase/uno/unotxdoc.cxx 
b/sw/source/uibase/uno/unotxdoc.cxx
index 07b052541eb4..85950c3e5c93 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3942,7 +3942,7 @@ void SwXTextDocument::resetSelection()
     SolarMutexGuard aGuard;
 
     SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
-    pWrtShell->ResetSelect(nullptr, false);
+    pWrtShell->ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
 }
 
 void SAL_CALL SwXTextDocument::paintTile( const ::css::uno::Any& Parent, 
::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, 
::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight )
diff --git a/sw/source/uibase/wrtsh/move.cxx b/sw/source/uibase/wrtsh/move.cxx
index f68e08010f9a..2f9f1e275ea0 100644
--- a/sw/source/uibase/wrtsh/move.cxx
+++ b/sw/source/uibase/wrtsh/move.cxx
@@ -85,7 +85,7 @@ void SwWrtShell::MoveCursor( bool bWithSelect )
     else
     {
         EndSelect();
-        (this->*m_fnKillSel)( nullptr, false );
+        (this->*m_fnKillSel)( nullptr, false, 
ScrollSizeMode::ScrollSizeDefault );
     }
 }
 
@@ -505,7 +505,7 @@ bool SwWrtShell::PushCursor(SwTwips lOffset, bool bSelect)
             CallChgLnk();
         }
 
-        (this->*m_fnSetCursor)( &m_aDest, true );
+        (this->*m_fnSetCursor)( &m_aDest, true, 
ScrollSizeMode::ScrollSizeDefault );
 
         bDiff = aOldRect != GetCharRect();
 
@@ -546,7 +546,7 @@ bool SwWrtShell::PopCursor(bool bUpdate, bool bSelect)
             else
                 EndSelect();
 
-            (this->*m_fnSetCursor)(&m_pCursorStack->aDocPos, 
!m_pCursorStack->bIsFrameSel);
+            (this->*m_fnSetCursor)(&m_pCursorStack->aDocPos, 
!m_pCursorStack->bIsFrameSel, ScrollSizeMode::ScrollSizeDefault);
             if( m_pCursorStack->bIsFrameSel && 
IsObjSelectable(m_pCursorStack->aDocPos))
             {
                 HideCursor();
diff --git a/sw/source/uibase/wrtsh/select.cxx 
b/sw/source/uibase/wrtsh/select.cxx
index 404ee207e5c6..1c2cfb39ced7 100644
--- a/sw/source/uibase/wrtsh/select.cxx
+++ b/sw/source/uibase/wrtsh/select.cxx
@@ -318,7 +318,7 @@ void SwWrtShell::PopMode()
 // eponymous methods in the CursorShell, the second removes
 // all selections at first.
 
-tools::Long SwWrtShell::SetCursor(const Point *pPt, bool bTextOnly)
+tools::Long SwWrtShell::SetCursor(const Point *pPt, bool bTextOnly, 
ScrollSizeMode eScrollSizeMode)
 {
         // Remove a possibly present selection at the position
         // of the mouseclick
@@ -327,14 +327,14 @@ tools::Long SwWrtShell::SetCursor(const Point *pPt, bool 
bTextOnly)
         ClearMark();
     }
 
-    return SwCursorShell::SetCursor(*pPt, bTextOnly);
+    return SwCursorShell::SetCursor(*pPt, bTextOnly, true, false, 
eScrollSizeMode );
 }
 
-tools::Long SwWrtShell::SetCursorKillSel(const Point *pPt, bool bTextOnly )
+tools::Long SwWrtShell::SetCursorKillSel(const Point *pPt, bool bTextOnly, 
ScrollSizeMode eScrollSizeMode )
 {
     SwActContext aActContext(this);
-    ResetSelect(pPt,false);
-    return SwCursorShell::SetCursor(*pPt, bTextOnly);
+    ResetSelect(pPt, false, ScrollSizeMode::ScrollSizeDefault);
+    return SwCursorShell::SetCursor(*pPt, bTextOnly, true, false, 
eScrollSizeMode);
 }
 
 void SwWrtShell::UnSelectFrame()
@@ -347,7 +347,7 @@ void SwWrtShell::UnSelectFrame()
 
 // Remove of all selections
 
-tools::Long SwWrtShell::ResetSelect(const Point *,bool)
+tools::Long SwWrtShell::ResetSelect(const Point *, bool, ScrollSizeMode)
 {
     if(IsSelFrameMode())
     {
@@ -393,7 +393,8 @@ void SwWrtShell::SetSplitVerticalByDefault(bool value)
 
 // Do nothing
 
-tools::Long SwWrtShell::Ignore(const Point *, bool ) {
+tools::Long SwWrtShell::Ignore(const Point *, bool, ScrollSizeMode )
+{
     return 1;
 }
 
@@ -674,7 +675,6 @@ void SwWrtShell::EnterAddMode()
     if(IsTableMode()) return;
     if(m_bBlockMode)
         LeaveBlockMode();
-    m_fnKillSel = &SwWrtShell::Ignore;
     m_fnSetCursor = &SwWrtShell::SetCursor;
     m_bAddMode = true;
     m_bBlockMode = false;
diff --git a/sw/source/uibase/wrtsh/wrtsh3.cxx 
b/sw/source/uibase/wrtsh/wrtsh3.cxx
index d441dcf89659..090e5a89798f 100644
--- a/sw/source/uibase/wrtsh/wrtsh3.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh3.cxx
@@ -49,7 +49,7 @@ using namespace ::com::sun::star;
 bool SwWrtShell::MoveBookMark( BookMarkMove eFuncId, const ::sw::mark::IMark* 
const pMark)
 {
     addCurrentPosition();
-    (this->*m_fnKillSel)( nullptr, false );
+    (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault );
 
     bool bRet = true;
     switch(eFuncId)
@@ -75,7 +75,7 @@ bool SwWrtShell::MoveBookMark( BookMarkMove eFuncId, const 
::sw::mark::IMark* co
 
 bool SwWrtShell::GotoField( const SwFormatField& rField )
 {
-    (this->*m_fnKillSel)( nullptr, false );
+    (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault );
 
     bool bRet = SwCursorShell::GotoFormatField( rField );
     if( bRet && IsSelFrameMode() )
@@ -122,7 +122,7 @@ bool SwWrtShell::GotoContentControl(const 
SwFormatContentControl& rContentContro
         return true;
     }
 
-    (this->*m_fnKillSel)(nullptr, false);
+    (this->*m_fnKillSel)(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
 
     bool bRet = SwCursorShell::GotoFormatContentControl(rContentControl);
 
@@ -223,7 +223,7 @@ bool SwWrtShell::GotoContentControl(const 
SwFormatContentControl& rContentContro
 
 bool SwWrtShell::GotoFieldmark(::sw::mark::IFieldmark const * const pMark)
 {
-    (this->*m_fnKillSel)( nullptr, false );
+    (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault );
     bool bRet = SwCursorShell::GotoFieldmark(pMark);
     if( bRet && IsSelFrameMode() )
     {

Reply via email to