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 47bf215cc7693bde89143f63b88556c61a68a132 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 Jan 21 12:13:16 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. Change-Id: Ifd21c92936021f8e2213d34446672e2a8eab568f 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> diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx index 08aae0878d93..773379e1eb0a 100644 --- a/sw/inc/crsrsh.hxx +++ b/sw/inc/crsrsh.hxx @@ -168,7 +168,7 @@ public: SW_DLLPUBLIC void UpdateCursor( sal_uInt16 eFlags = SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, - bool bIdleEnd = false ); + bool bIdleEnd = false, ScrollSizeMode eScrollSizeMode = ScrollSizeMode::ScrollSizeDefault ); private: @@ -422,7 +422,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 @@ -735,7 +735,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; @@ -817,7 +817,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 94f5f0d3c09e..c1b1ae7e9881 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 3eba3163d333..220c97af2627 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> @@ -302,7 +303,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; @@ -447,7 +449,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 b75ff5009d83..7b2565f18703 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; @@ -286,7 +293,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 12ded9650e55..3ef4fd73b492 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -1056,7 +1056,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 ); @@ -1161,7 +1162,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() ) @@ -1943,7 +1944,7 @@ class SwNotifyAccAboutInvalidTextSelections } #endif -void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd ) +void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd, ScrollSizeMode eScrollSizeMode ) { Point nOldPos = m_pCurrentCursor->GetPtPos(); CurrShell aCurr( this ); @@ -2387,7 +2388,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; } @@ -3093,7 +3094,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 ); @@ -3132,7 +3133,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); } @@ -3520,7 +3521,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() ) @@ -3544,13 +3545,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 4fc5286e0101..1e2d117e759c 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -2669,7 +2669,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() ) @@ -2678,7 +2678,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 9e3820953de6..e8db55ee359c 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -682,7 +682,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; @@ -698,7 +698,7 @@ void SwViewShell::MakeVisible( const SwRect &rRect ) do{ nOldH = pRoot->getFrameArea().Height(); SwViewShell::StartAction(); - ScrollMDI( this, rRect, USHRT_MAX, USHRT_MAX ); + ScrollMDI( this, rRect, USHRT_MAX, USHRT_MAX, eScrollSizeMode ); SwViewShell::EndAction(); // DO NOT call virtual here! } while( nOldH != pRoot->getFrameArea().Height() && nLoopCnt-- ); } diff --git a/sw/source/ui/dialog/uiregionsw.cxx b/sw/source/ui/dialog/uiregionsw.cxx index 16c6cda95b58..92dccb18e1da 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 2bc41b0889a4..58a0f1f65621 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 dacf8308fe72..a43bd61eacd8 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 @@ void SwInsFootNoteDlg::ImplDestroy() SwViewShell::SetCareDialog(nullptr); if (m_bEdit) - m_rSh.ResetSelect(nullptr, false); + m_rSh.ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault); } SwInsFootNoteDlg::~SwInsFootNoteDlg() diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index 5f775e7a3d96..11847f90b53d 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -3877,7 +3877,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 72e50a65599e..89f93144919d 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 f8ce91be0426..efaf125578e9 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -682,7 +682,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. @@ -706,15 +706,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) @@ -3970,7 +3975,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) @@ -4569,8 +4574,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(); } } @@ -5498,6 +5503,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 ), @@ -6312,7 +6318,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 4a60637c9624..432e58fc2d5e 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 53e7ddf16568..bb87a61a39ca 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 bc9763c0b1e0..21a59b8c039b 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(); @@ -614,9 +618,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 ); @@ -632,7 +638,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 e75bb001df08..3664e17c50de 100644 --- a/sw/source/uibase/shells/tabsh.cxx +++ b/sw/source/uibase/shells/tabsh.cxx @@ -858,7 +858,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 0c357d1d77d0..6ec961fcac00 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -1144,7 +1144,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 f511f4a8e354..4fab16ff7755 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 7052d22ca1c1..000564fbbc76 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -4072,7 +4072,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 784a3992d584..a2c50dae8582 100644 --- a/sw/source/uibase/wrtsh/move.cxx +++ b/sw/source/uibase/wrtsh/move.cxx @@ -84,7 +84,7 @@ void SwWrtShell::MoveCursor( bool bWithSelect ) else { EndSelect(); - (this->*m_fnKillSel)( nullptr, false ); + (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault ); } } @@ -498,7 +498,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(); @@ -539,7 +539,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 7d15d2cb4d68..fc502783003b 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 36c12ebee17c..2a83ebaeb48f 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::MarkBase* 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::MarkBase* 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::Fieldmark const * const pMark) { - (this->*m_fnKillSel)( nullptr, false ); + (this->*m_fnKillSel)( nullptr, false, ScrollSizeMode::ScrollSizeDefault ); bool bRet = SwCursorShell::GotoFieldmark(pMark); if( bRet && IsSelFrameMode() ) {