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() ) {