1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/commandevent.hxx>
21 #include <vcl/help.hxx>
22 #include <vcl/settings.hxx>
23 #include <vcl/syswin.hxx>
25 #include <svx/ruler.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/viewfrm.hxx>
30 #include <viewopt.hxx>
36 #include <PostItMgr.hxx>
38 #include <basegfx/utils/zoomtools.hxx>
39 #include <comphelper/lok.hxx>
40 #include <vcl/weld.hxx>
41 #include <tools/svborder.hxx>
42 #include <osl/diagnose.h>
44 #include "viewfunc.hxx"
46 #include <FrameControlsManager.hxx>
48 // The SetVisArea of the DocShell must not be called from InnerResizePixel.
49 // But our adjustments must take place.
50 static bool bProtectDocShellVisArea
= false;
52 static sal_uInt16 nPgNum
= 0;
54 bool SwView::IsDocumentBorder()
56 if (GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
62 return m_pWrtShell
->GetViewOptions()->getBrowseMode() ||
63 SvxZoomType::PAGEWIDTH_NOBORDER
== m_pWrtShell
->GetViewOptions()->GetZoomType();
66 static tools::Long
GetLeftMargin( SwView
const &rView
)
68 SvxZoomType eType
= rView
.GetWrtShell().GetViewOptions()->GetZoomType();
69 tools::Long lRet
= rView
.GetWrtShell().GetAnyCurRect(CurRectType::PagePrt
).Left();
70 return eType
== SvxZoomType::PERCENT
? lRet
+ DOCUMENTBORDER
:
71 eType
== SvxZoomType::PAGEWIDTH
|| eType
== SvxZoomType::PAGEWIDTH_NOBORDER
? 0 :
72 lRet
+ DOCUMENTBORDER
+ nLeftOfst
;
75 static void lcl_GetPos(SwView
const * pView
,
77 const weld::Scrollbar
& rScrollbar
,
81 SwWrtShell
&rSh
= pView
->GetWrtShell();
82 const Size
aDocSz( rSh
.GetDocSize() );
84 const tools::Long lBorder
= bBorder
? DOCUMENTBORDER
: DOCUMENTBORDER
* 2;
86 const tools::Long lPos
= rScrollbar
.adjustment_get_value() + (bBorder
? DOCUMENTBORDER
: 0);
88 tools::Long lDelta
= lPos
- (bHori
? rSh
.VisArea().Pos().X() : rSh
.VisArea().Pos().Y());
90 const tools::Long lSize
= (bHori
? aDocSz
.Width() : aDocSz
.Height()) + lBorder
;
91 // Should right or below are too much space,
92 // then they must be subtracted out of the VisArea!
93 tools::Long nTmp
= pView
->GetVisArea().Right()+lDelta
;
94 if ( bHori
&& nTmp
> lSize
)
95 lDelta
-= nTmp
- lSize
;
96 nTmp
= pView
->GetVisArea().Bottom()+lDelta
;
97 if ( !bHori
&& nTmp
> lSize
)
98 lDelta
-= nTmp
- lSize
;
100 bHori
? rPos
.AdjustX(lDelta
) : rPos
.AdjustY(lDelta
);
101 if ( bBorder
&& (bHori
? rPos
.X() : rPos
.Y()) < DOCUMENTBORDER
)
102 bHori
? rPos
.setX(DOCUMENTBORDER
) : rPos
.setY(DOCUMENTBORDER
);
107 void SwView::InvalidateRulerPos()
109 static sal_uInt16 aInval
[] =
111 SID_ATTR_PARA_LRSPACE
, SID_RULER_BORDERS
, SID_RULER_PAGE_POS
,
112 SID_RULER_LR_MIN_MAX
, SID_ATTR_LONG_ULSPACE
, SID_ATTR_LONG_LRSPACE
,
113 SID_RULER_BORDER_DISTANCE
,
114 SID_ATTR_PARA_LRSPACE_VERTICAL
, SID_RULER_BORDERS_VERTICAL
,
115 SID_RULER_TEXT_RIGHT_TO_LEFT
,
116 SID_RULER_ROWS
, SID_RULER_ROWS_VERTICAL
, FN_STAT_PAGE
,
120 GetViewFrame().GetBindings().Invalidate(aInval
);
122 assert(m_pHRuler
&& "Why is the ruler not there?");
123 m_pHRuler
->ForceUpdate();
124 m_pVRuler
->ForceUpdate();
127 // Limits the scrolling so far that only a quarter of the
128 // screen can be scrolled up before the end of the document.
130 tools::Long
SwView::SetHScrollMax( tools::Long lMax
)
132 const tools::Long lBorder
= IsDocumentBorder() ? DOCUMENTBORDER
: DOCUMENTBORDER
* 2;
133 const tools::Long lSize
= GetDocSz().Width() + lBorder
- m_aVisArea
.GetWidth();
135 // At negative values the document is completely visible.
136 // In this case, no scrolling.
137 return std::clamp( lSize
, tools::Long(0), lMax
);
140 tools::Long
SwView::SetVScrollMax( tools::Long lMax
)
142 const tools::Long lBorder
= IsDocumentBorder() ? DOCUMENTBORDER
: DOCUMENTBORDER
* 2;
143 tools::Long lSize
= GetDocSz().Height() + lBorder
- m_aVisArea
.GetHeight();
144 return std::clamp( lSize
, tools::Long(0), lMax
); // see horizontal
147 Point
SwView::AlignToPixel(const Point
&rPt
) const
149 return GetEditWin().PixelToLogic( GetEditWin().LogicToPixel( rPt
) );
152 // Document size has changed.
154 void SwView::DocSzChgd(const Size
&rSz
)
158 if( !m_pWrtShell
|| m_aVisArea
.IsEmpty() ) // no shell -> no change
160 bDocSzUpdated
= false;
164 //If text has been deleted, it may be that the VisArea points behind the visible range.
165 tools::Rectangle
aNewVisArea( m_aVisArea
);
166 bool bModified
= false;
167 SwTwips lGreenOffset
= IsDocumentBorder() ? DOCUMENTBORDER
: DOCUMENTBORDER
* 2;
168 SwTwips lTmp
= m_aDocSz
.Width() + lGreenOffset
;
170 if ( aNewVisArea
.Right() >= lTmp
)
172 lTmp
= aNewVisArea
.Right() - lTmp
;
173 aNewVisArea
.AdjustRight( -lTmp
);
174 aNewVisArea
.AdjustLeft( -lTmp
);
178 lTmp
= m_aDocSz
.Height() + lGreenOffset
;
179 if ( aNewVisArea
.Bottom() >= lTmp
)
181 lTmp
= aNewVisArea
.Bottom() - lTmp
;
182 aNewVisArea
.AdjustBottom( -lTmp
);
183 aNewVisArea
.AdjustTop( -lTmp
);
188 SetVisArea( aNewVisArea
, false );
190 if ( UpdateScrollbars() && !m_bInOuterResizePixel
&& !m_bInInnerResizePixel
&&
191 !GetViewFrame().GetFrame().IsInPlace())
192 OuterResizePixel( Point(),
193 GetViewFrame().GetWindow().GetOutputSizePixel() );
198 void SwView::SetVisArea( const tools::Rectangle
&rRect
, bool bUpdateScrollbar
)
200 Size
aOldSz( m_aVisArea
.GetSize() );
201 if (comphelper::LibreOfficeKit::isActive() && m_pWrtShell
)
202 // If m_pWrtShell's visible area is the whole document, do the same here.
203 aOldSz
= m_pWrtShell
->VisArea().SSize();
205 if( rRect
== m_aVisArea
)
208 const SwTwips lMin
= IsDocumentBorder() ? DOCUMENTBORDER
: 0;
210 // No negative position, no negative size
211 tools::Rectangle aLR
= rRect
;
212 if( aLR
.Top() < lMin
)
214 aLR
.AdjustBottom(lMin
- aLR
.Top() );
217 if( aLR
.Left() < lMin
)
219 aLR
.AdjustRight(lMin
- aLR
.Left() );
222 if( aLR
.Right() < 0 )
224 if( aLR
.Bottom() < 0 )
227 if( aLR
== m_aVisArea
)
230 const Size
aSize( aLR
.GetSize() );
231 if( aSize
.IsEmpty() )
234 // Before the data can be changed, call an update if necessary. This
235 // ensures that adjacent Paints in document coordinates are converted
237 // As a precaution, we do this only when an action is running in the
238 // shell, because then it is not really drawn but the rectangles will
239 // be only marked (in document coordinates).
240 if ( m_pWrtShell
&& m_pWrtShell
->ActionPend() )
241 m_pWrtShell
->GetWin()->PaintImmediately();
245 const bool bOuterResize
= bUpdateScrollbar
&& UpdateScrollbars();
249 m_pWrtShell
->VisPortChgd( SwRect(m_aVisArea
) );
250 if ( aOldSz
!= m_pWrtShell
->VisArea().SSize() &&
251 ( std::abs(aOldSz
.Width() - m_pWrtShell
->VisArea().Width()) > 2 ||
252 std::abs(aOldSz
.Height() - m_pWrtShell
->VisArea().Height()) > 2 ) )
253 m_pWrtShell
->InvalidateLayout( false );
256 if ( !bProtectDocShellVisArea
)
258 // If the size of VisArea is unchanged, we extend the size of the VisArea
259 // InternalObject on. By that the transport of errors shall be avoided.
260 tools::Rectangle
aVis( m_aVisArea
);
261 if ( aVis
.GetSize() == aOldSz
)
262 aVis
.SetSize( GetDocShell()->SfxObjectShell::GetVisArea(ASPECT_CONTENT
).GetSize() );
263 // TODO/LATER: why casting?!
264 //GetDocShell()->SfxInPlaceObject::GetVisArea().GetSize() );
266 // With embedded always with modify...
267 // TODO/LATER: why casting?!
268 GetDocShell()->SfxObjectShell::SetVisArea( aVis
);
270 if ( GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
271 GetDocShell()->SfxInPlaceObject::SetVisArea( aVis );
273 GetDocShell()->SvEmbeddedObject::SetVisArea( aVis );*/
276 SfxViewShell::VisAreaChanged();
278 InvalidateRulerPos();
280 if ( bOuterResize
&& !m_bInOuterResizePixel
&& !m_bInInnerResizePixel
)
281 OuterResizePixel( Point(),
282 GetViewFrame().GetWindow().GetOutputSizePixel() );
287 void SwView::SetVisArea( const Point
&rPt
, bool bUpdateScrollbar
)
289 // Align once, so brushes will be inserted correctly.
290 // This goes wrong in the BrowseView, because the entire document may
291 // not be visible. Since the content in frames is fitting exactly,
292 // align is not possible (better idea?!?!)
293 // (fix: Bild.de, 200%) It does not work completely without alignment
294 // Let's see how far we get with half BrushSize.
295 Point aPt
= GetEditWin().LogicToPixel( rPt
);
296 #if HAVE_FEATURE_DESKTOP
297 const tools::Long nTmp
= GetWrtShell().IsFrameView() ? 4 : 8;
298 aPt
.AdjustX( -(aPt
.X() % nTmp
) );
299 aPt
.AdjustY( -(aPt
.Y() % nTmp
) );
301 aPt
= GetEditWin().PixelToLogic( aPt
);
303 if ( aPt
== m_aVisArea
.TopLeft() )
306 if (GetWrtShell().GetViewOptions()->IsShowOutlineContentVisibilityButton())
307 GetEditWin().GetFrameControlsManager().HideControls(FrameControlType::Outline
);
309 const tools::Long lXDiff
= m_aVisArea
.Left() - aPt
.X();
310 const tools::Long lYDiff
= m_aVisArea
.Top() - aPt
.Y();
311 SetVisArea( tools::Rectangle( aPt
,
312 Point( m_aVisArea
.Right() - lXDiff
, m_aVisArea
.Bottom() - lYDiff
) ),
316 void SwView::CheckVisArea()
318 m_pHScrollbar
->SetAuto( m_pWrtShell
->GetViewOptions()->getBrowseMode() &&
319 !GetViewFrame().GetFrame().IsInPlace() );
320 if ( IsDocumentBorder() )
322 if ( m_aVisArea
.Left() != DOCUMENTBORDER
||
323 m_aVisArea
.Top() != DOCUMENTBORDER
)
325 tools::Rectangle
aNewVisArea( m_aVisArea
);
326 aNewVisArea
.Move( DOCUMENTBORDER
- m_aVisArea
.Left(),
327 DOCUMENTBORDER
- m_aVisArea
.Top() );
328 SetVisArea( aNewVisArea
);
333 /// Calculate the visible range.
335 // OUT Point *pPt: new position of the visible area
337 // IN Rectangle &rRect: Rectangle, which should be located
338 // within the new visible area.
339 // sal_uInt16 nRange optional accurate indication of the
340 // range by which to scroll if necessary.
342 void SwView::CalcPt( Point
*pPt
, const tools::Rectangle
&rRect
,
343 sal_uInt16 nRangeX
, sal_uInt16 nRangeY
)
346 const SwTwips lMin
= IsDocumentBorder() ? DOCUMENTBORDER
: 0;
348 tools::Long nYScroll
= GetYScroll();
349 tools::Long nDesHeight
= rRect
.GetHeight();
350 tools::Long nCurHeight
= m_aVisArea
.GetHeight();
351 nYScroll
= std::min(nYScroll
, nCurHeight
- nDesHeight
); // If it is scarce, then scroll not too much.
352 if(nDesHeight
> nCurHeight
) // the height is not sufficient, then nYScroll is no longer of interest
354 pPt
->setY( rRect
.Top() );
355 pPt
->setY( std::max( lMin
, SwTwips(pPt
->Y()) ) );
357 else if ( rRect
.Top() < m_aVisArea
.Top() ) // Upward shift
359 pPt
->setY( rRect
.Top() - (nRangeY
!= USHRT_MAX
? nRangeY
: nYScroll
) );
360 pPt
->setY( std::max( lMin
, SwTwips(pPt
->Y()) ) );
362 else if( rRect
.Bottom() > m_aVisArea
.Bottom() ) // Downward shift
364 pPt
->setY( rRect
.Bottom() -
365 (m_aVisArea
.GetHeight()) + ( nRangeY
!= USHRT_MAX
?
366 nRangeY
: nYScroll
) );
367 pPt
->setY( SetVScrollMax( pPt
->Y() ) );
369 tools::Long nXScroll
= GetXScroll();
370 if ( rRect
.Right() > m_aVisArea
.Right() ) // Shift right
372 pPt
->setX( rRect
.Right() -
373 (m_aVisArea
.GetWidth()) +
374 (nRangeX
!= USHRT_MAX
? nRangeX
: nXScroll
) );
375 pPt
->setX( SetHScrollMax( pPt
->X() ) );
377 else if ( rRect
.Left() < m_aVisArea
.Left() ) // Shift left
379 pPt
->setX( rRect
.Left() - (nRangeX
!= USHRT_MAX
? nRangeX
: nXScroll
) );
380 pPt
->setX( std::max( ::GetLeftMargin( *this ) + nLeftOfst
, pPt
->X() ) );
381 pPt
->setX( std::min( rRect
.Left() - nScrollX
, pPt
->X() ) );
382 pPt
->setX( std::max( tools::Long(0), pPt
->X() ) );
388 bool SwView::IsScroll( const tools::Rectangle
&rRect
) const
390 return m_bCenterCursor
|| m_bTopCursor
|| !m_aVisArea
.Contains(rRect
);
393 void SwView::Scroll( const tools::Rectangle
&rRect
, sal_uInt16 nRangeX
, sal_uInt16 nRangeY
)
395 if ( m_aVisArea
.IsEmpty() )
398 tools::Rectangle
aOldVisArea( m_aVisArea
);
399 tools::Long nDiffY
= 0;
401 weld::Window
* pCareDialog
= SwViewShell::GetCareDialog(GetWrtShell());
404 int x
, y
, width
, height
;
405 tools::Rectangle aDlgRect
;
406 if (pCareDialog
->get_extents_relative_to(*GetEditWin().GetFrameWeld(), x
, y
, width
, height
))
408 Point
aTopLeft(GetEditWin().GetSystemWindow()->OutputToAbsoluteScreenPixel(Point(x
, y
)));
409 aTopLeft
= GetEditWin().AbsoluteScreenToOutputPixel(aTopLeft
);
410 aDlgRect
= GetEditWin().PixelToLogic(tools::Rectangle(aTopLeft
, Size(width
, height
)));
413 // Only if the dialogue is not the VisArea right or left:
414 if ( aDlgRect
.Left() < m_aVisArea
.Right() &&
415 aDlgRect
.Right() > m_aVisArea
.Left() )
417 // If we are not supposed to be centered, lying in the VisArea
418 // and are not covered by the dialogue ...
419 if ( !m_bCenterCursor
&& aOldVisArea
.Contains( rRect
)
420 && ( rRect
.Left() > aDlgRect
.Right()
421 || rRect
.Right() < aDlgRect
.Left()
422 || rRect
.Top() > aDlgRect
.Bottom()
423 || rRect
.Bottom() < aDlgRect
.Top() ) )
426 // Is above or below the dialogue more space?
427 tools::Long nTopDiff
= aDlgRect
.Top() - m_aVisArea
.Top();
428 tools::Long nBottomDiff
= m_aVisArea
.Bottom() - aDlgRect
.Bottom();
429 if ( nTopDiff
< nBottomDiff
)
431 if ( nBottomDiff
> 0 ) // Is there room below at all?
432 { // then we move the upper edge and we remember this
433 nDiffY
= aDlgRect
.Bottom() - m_aVisArea
.Top();
434 m_aVisArea
.AdjustTop(nDiffY
);
439 if ( nTopDiff
> 0 ) // Is there room below at all?
440 m_aVisArea
.SetBottom( aDlgRect
.Top() ); // Modify the lower edge
446 if( !(m_bCenterCursor
|| m_bTopCursor
) && m_aVisArea
.Contains( rRect
) )
448 m_aVisArea
= aOldVisArea
;
451 // If the rectangle is larger than the visible area -->
453 Size
aSize( rRect
.GetSize() );
454 const Size
aVisSize( m_aVisArea
.GetSize() );
455 if( !m_aVisArea
.IsEmpty() && (
456 aSize
.Width() + GetXScroll() > aVisSize
.Width() ||
457 aSize
.Height()+ GetYScroll() > aVisSize
.Height() ))
459 Point
aPt( m_aVisArea
.TopLeft() );
460 aSize
.setWidth( std::min( aSize
.Width(), aVisSize
.Width() ) );
461 aSize
.setHeight( std::min( aSize
.Height(),aVisSize
.Height()) );
463 CalcPt( &aPt
, tools::Rectangle( rRect
.TopLeft(), aSize
),
464 static_cast< sal_uInt16
>((aVisSize
.Width() - aSize
.Width()) / 2),
465 static_cast< sal_uInt16
>((aVisSize
.Height()- aSize
.Height())/ 2) );
469 const tools::Long nBorder
= IsDocumentBorder() ? DOCUMENTBORDER
: 0;
470 aPt
.setY( std::min( std::max( nBorder
, rRect
.Top() ),
471 m_aDocSz
.Height() + nBorder
-
472 m_aVisArea
.GetHeight() ) );
474 aPt
.AdjustY( -nDiffY
);
475 m_aVisArea
= aOldVisArea
;
479 if( !m_bCenterCursor
)
481 Point
aPt( m_aVisArea
.TopLeft() );
482 CalcPt( &aPt
, rRect
, nRangeX
, nRangeY
);
486 const tools::Long nBorder
= IsDocumentBorder() ? DOCUMENTBORDER
: 0;
487 aPt
.setY( std::min( std::max( nBorder
, rRect
.Top() ),
488 m_aDocSz
.Height() + nBorder
-
489 m_aVisArea
.GetHeight() ) );
492 aPt
.AdjustY( -nDiffY
);
493 m_aVisArea
= aOldVisArea
;
499 Point
aPnt( m_aVisArea
.TopLeft() );
500 // ... in Y-direction in any case
501 aPnt
.AdjustY(( rRect
.Top() + rRect
.Bottom()
502 - m_aVisArea
.Top() - m_aVisArea
.Bottom() ) / 2 - nDiffY
);
503 // ... in X-direction, only if the rectangle protrudes over the right or left of the VisArea.
504 if ( rRect
.Right() > m_aVisArea
.Right() || rRect
.Left() < m_aVisArea
.Left() )
506 aPnt
.AdjustX(( rRect
.Left() + rRect
.Right()
507 - m_aVisArea
.Left() - m_aVisArea
.Right() ) / 2 );
508 aPnt
.setX( SetHScrollMax( aPnt
.X() ) );
509 const SwTwips lMin
= IsDocumentBorder() ? DOCUMENTBORDER
: 0;
510 aPnt
.setX( std::max( (GetLeftMargin( *this ) - lMin
) + nLeftOfst
, aPnt
.X() ) );
512 m_aVisArea
= aOldVisArea
;
515 // If we want to avoid only a dialogue, we do
516 // not want to go beyond the end of the document.
517 aPnt
.setY( SetVScrollMax( aPnt
.Y() ) );
522 /// Scroll page by page
523 // Returns the value by which to be scrolled with PageUp / Down
525 bool SwView::GetPageScrollUpOffset( SwTwips
&rOff
) const
527 // in the LOK case, force the value set by the API
528 if (comphelper::LibreOfficeKit::isActive() && m_nLOKPageUpDownOffset
> 0)
530 rOff
= -m_nLOKPageUpDownOffset
;
534 if ( !m_aVisArea
.Top() || !m_aVisArea
.GetHeight() )
536 tools::Long nYScrl
= GetYScroll() / 2;
537 rOff
= -(m_aVisArea
.GetHeight() - nYScrl
);
538 // Do not scroll before the beginning of the document.
539 if( m_aVisArea
.Top() - rOff
< 0 )
540 rOff
= rOff
- m_aVisArea
.Top();
541 else if( GetWrtShell().GetCharRect().Top() < (m_aVisArea
.Top() + nYScrl
))
547 bool SwView::GetPageScrollDownOffset( SwTwips
&rOff
) const
549 // in the LOK case, force the value set by the API
550 if (comphelper::LibreOfficeKit::isActive() && m_nLOKPageUpDownOffset
> 0)
552 rOff
= m_nLOKPageUpDownOffset
;
556 if ( !m_aVisArea
.GetHeight() ||
557 (m_aVisArea
.GetHeight() > m_aDocSz
.Height()) )
559 tools::Long nYScrl
= GetYScroll() / 2;
560 rOff
= m_aVisArea
.GetHeight() - nYScrl
;
561 // Do not scroll past the end of the document.
562 if ( m_aVisArea
.Top() + rOff
> m_aDocSz
.Height() )
563 rOff
= m_aDocSz
.Height() - m_aVisArea
.Bottom();
564 else if( GetWrtShell().GetCharRect().Bottom() >
565 ( m_aVisArea
.Bottom() - nYScrl
))
571 // Scroll page by page
572 bool SwView::PageUp()
574 if (!m_aVisArea
.GetHeight())
577 Point
aPos(m_aVisArea
.TopLeft());
578 aPos
.AdjustY( -(m_aVisArea
.GetHeight() - (GetYScroll() / 2)) );
579 aPos
.setY( std::max(tools::Long(0), aPos
.Y()) );
584 bool SwView::PageDown()
586 if ( !m_aVisArea
.GetHeight() )
588 Point
aPos( m_aVisArea
.TopLeft() );
589 aPos
.AdjustY(m_aVisArea
.GetHeight() - (GetYScroll() / 2) );
590 aPos
.setY( SetVScrollMax( aPos
.Y() ) );
595 void SwView::PhyPageUp()
597 // Check for the currently visible page, do not format
598 sal_uInt16 nActPage
= m_pWrtShell
->GetNextPrevPageNum( false );
600 if( USHRT_MAX
!= nActPage
)
602 const Point
aPt( m_aVisArea
.Left(),
603 m_pWrtShell
->GetPagePos( nActPage
).Y() );
604 Point
aAlPt( AlignToPixel( aPt
) );
605 // If there is a difference, has been truncated --> then add one pixel,
606 // so that no residue of the previous page is visible.
607 if( aPt
.Y() != aAlPt
.Y() )
608 aAlPt
.AdjustY(3 * GetEditWin().PixelToLogic( Size( 0, 1 ) ).Height() );
613 void SwView::PhyPageDown()
615 // Check for the currently visible page, do not format
616 sal_uInt16 nActPage
= m_pWrtShell
->GetNextPrevPageNum();
617 // If the last page of the document is visible, do nothing.
618 if( USHRT_MAX
!= nActPage
)
620 const Point
aPt( m_aVisArea
.Left(),
621 m_pWrtShell
->GetPagePos( nActPage
).Y() );
622 Point
aAlPt( AlignToPixel( aPt
) );
623 // If there is a difference, has been truncated --> then add one pixel,
624 // so that no residue of the previous page is visible.
625 if( aPt
.Y() != aAlPt
.Y() )
626 aAlPt
.AdjustY(3 * GetEditWin().PixelToLogic( Size( 0, 1 ) ).Height() );
631 bool SwView::PageUpCursor( bool bSelect
)
635 const FrameTypeFlags eType
= m_pWrtShell
->GetFrameType(nullptr,true);
636 if ( eType
& FrameTypeFlags::FOOTNOTE
)
638 m_pWrtShell
->MoveCursor();
639 m_pWrtShell
->GotoFootnoteAnchor();
640 m_pWrtShell
->Right(SwCursorSkipMode::Chars
, false, 1, false );
646 if ( GetPageScrollUpOffset( lOff
) &&
647 (m_pWrtShell
->IsCursorReadonly() ||
648 !m_pWrtShell
->PageCursor( lOff
, bSelect
)) &&
651 m_pWrtShell
->ResetCursorStack();
657 bool SwView::PageDownCursor(bool bSelect
)
660 if ( GetPageScrollDownOffset( lOff
) &&
661 (m_pWrtShell
->IsCursorReadonly() ||
662 !m_pWrtShell
->PageCursor( lOff
, bSelect
)) &&
665 m_pWrtShell
->ResetCursorStack();
671 // Handler of the scrollbars
672 IMPL_LINK(SwView
, VertScrollHdl
, weld::Scrollbar
&, rScrollbar
, void)
674 if ( GetWrtShell().ActionPend() )
677 if (rScrollbar
.get_scroll_type() == ScrollType::Drag
)
678 m_pWrtShell
->EnableSmooth( false );
680 EndScrollHdl(rScrollbar
, false);
682 if (!m_pWrtShell
->GetViewOptions()->getBrowseMode() &&
683 rScrollbar
.get_scroll_type() == ScrollType::Drag
)
685 if ( !m_bWheelScrollInProgress
&& Help::IsQuickHelpEnabled() &&
686 m_pWrtShell
->GetViewOptions()->IsShowScrollBarTips())
689 Point
aPos( m_aVisArea
.TopLeft() );
690 lcl_GetPos(this, aPos
, rScrollbar
, false, IsDocumentBorder());
692 sal_uInt16 nPhNum
= 1;
693 sal_uInt16 nVirtNum
= 1;
696 if(m_pWrtShell
->GetPageNumber( aPos
.Y(), false, nPhNum
, nVirtNum
, sDisplay
))
698 // The end scrollhandler invalidate the FN_STAT_PAGE,
699 // so we don't must do it again.
700 // if(!GetViewFrame().GetFrame().IsInPlace())
701 // S F X_BINDINGS().Update(FN_STAT_PAGE);
704 if( m_pWrtShell
->GetPageCnt() > 1 )
706 if( !nPgNum
|| nPgNum
!= nPhNum
)
708 tools::Rectangle aRect
;
709 aRect
.SetLeft( m_pVScrollbar
->GetParent()->OutputToScreenPixel(
710 m_pVScrollbar
->GetPosPixel() ).X() -8 );
711 aRect
.SetTop( m_pVScrollbar
->OutputToScreenPixel(
712 m_pVScrollbar
->GetPointerPosPixel() ).Y() );
713 aRect
.SetRight( aRect
.Left() );
714 aRect
.SetBottom( aRect
.Top() );
716 OUString
sPageStr( GetPageStr( nPhNum
, nVirtNum
, sDisplay
));
717 SwContentAtPos
aCnt(IsAttrAtPos::Outline
| IsAttrAtPos::AllowContaining
);
718 bool bSuccess
= m_pWrtShell
->GetContentAtPos(aPos
, aCnt
);
719 if (bSuccess
&& !aCnt
.sStr
.isEmpty())
721 sal_Int32 nChunkLen
= std::min
<sal_Int32
>(aCnt
.sStr
.getLength(), 80);
722 std::u16string_view sChunk
= aCnt
.sStr
.subView(0, nChunkLen
);
723 sPageStr
= sPageStr
+ " - " + sChunk
;
724 sPageStr
= sPageStr
.replace('\t', ' ').replace(0x0a, ' ');
727 Help::ShowQuickHelp(m_pVScrollbar
, aRect
, sPageStr
,
728 QuickHelpFlags::Right
|QuickHelpFlags::VCenter
);
736 if (rScrollbar
.get_scroll_type() == ScrollType::Drag
)
737 m_pWrtShell
->EnableSmooth( true );
740 // Handler of the scrollbars
741 void SwView::EndScrollHdl(weld::Scrollbar
& rScrollbar
, bool bHorizontal
)
743 if ( GetWrtShell().ActionPend() )
749 Help::ShowQuickHelp(bHorizontal
? m_pHScrollbar
: m_pVScrollbar
, tools::Rectangle(), OUString());
751 Point
aPos( m_aVisArea
.TopLeft() );
752 bool bBorder
= IsDocumentBorder();
753 lcl_GetPos(this, aPos
, rScrollbar
, bHorizontal
, bBorder
);
754 if ( bBorder
&& aPos
== m_aVisArea
.TopLeft() )
757 SetVisArea( aPos
, false );
759 GetViewFrame().GetBindings().Update(FN_STAT_PAGE
);
762 IMPL_LINK(SwView
, HoriScrollHdl
, weld::Scrollbar
&, rScrollBar
, void)
764 EndScrollHdl(rScrollBar
, true);
767 // Calculates the size of the m_aVisArea in dependency of the size of
768 // EditWin on the screen.
770 void SwView::CalcVisArea( const Size
&rOutPixel
)
773 tools::Rectangle
aRect( aTopLeft
, rOutPixel
);
774 aRect
= GetEditWin().PixelToLogic(aRect
);
776 // The shifts to the right and/or below can now be incorrect
777 // (e.g. change zoom level, change view size).
778 const tools::Long lBorder
= IsDocumentBorder() ? DOCUMENTBORDER
: DOCUMENTBORDER
*2;
781 const tools::Long lWidth
= GetWrtShell().GetDocSize().Width() + lBorder
;
782 if ( aRect
.Right() > lWidth
)
784 tools::Long lDelta
= aRect
.Right() - lWidth
;
785 aRect
.AdjustLeft( -lDelta
);
786 aRect
.AdjustRight( -lDelta
);
791 const tools::Long lHeight
= GetWrtShell().GetDocSize().Height() + lBorder
;
792 if ( aRect
.Bottom() > lHeight
)
794 tools::Long lDelta
= aRect
.Bottom() - lHeight
;
795 aRect
.AdjustTop( -lDelta
);
796 aRect
.AdjustBottom( -lDelta
);
800 GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOM
);
801 GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER
); // for snapping points
804 // Rearrange control elements
806 void SwView::CalcAndSetBorderPixel( SvBorder
&rToFill
)
808 bool bRightVRuler
= m_pWrtShell
->GetViewOptions()->IsVRulerRight();
809 if ( m_pVRuler
->IsVisible() )
811 tools::Long nWidth
= m_pVRuler
->GetSizePixel().Width();
813 rToFill
.Right() = nWidth
;
815 rToFill
.Left() = nWidth
;
818 OSL_ENSURE(m_pHRuler
, "Why is the ruler not present?");
819 if ( m_pHRuler
->IsVisible() )
820 rToFill
.Top() = m_pHRuler
->GetSizePixel().Height();
822 const StyleSettings
&rSet
= GetEditWin().GetSettings().GetStyleSettings();
823 const tools::Long nTmp
= rSet
.GetScrollBarSize();
824 if( m_pVScrollbar
->IsScrollbarVisible(true) )
827 rToFill
.Left() = nTmp
;
829 rToFill
.Right() = nTmp
;
831 if ( m_pHScrollbar
->IsScrollbarVisible(true) )
832 rToFill
.Bottom() = nTmp
;
834 SetBorderPixel( rToFill
);
837 void ViewResizePixel( const vcl::RenderContext
&rRef
,
841 SwScrollbar
& rVScrollbar
,
842 SwScrollbar
& rHScrollbar
,
847 // ViewResizePixel is also used by Preview!!!
849 const bool bHRuler
= pHRuler
&& pHRuler
->IsVisible();
850 const tools::Long nHLinSzHeight
= bHRuler
?
851 pHRuler
->GetSizePixel().Height() : 0;
852 const bool bVRuler
= pVRuler
&& pVRuler
->IsVisible();
853 const tools::Long nVLinSzWidth
= bVRuler
?
854 pVRuler
->GetSizePixel().Width() : 0;
856 const tools::Long nScrollBarSize
= rRef
.GetSettings().GetStyleSettings().GetScrollBarSize();
857 const tools::Long nHBSzHeight
= rHScrollbar
.IsScrollbarVisible(true) ? nScrollBarSize
: 0;
858 const tools::Long nVBSzWidth
= rVScrollbar
.IsScrollbarVisible(true) ? nScrollBarSize
: 0;
862 WinBits nStyle
= pVRuler
->GetStyle()&~WB_RIGHT_ALIGNED
;
863 Point
aPos( rOfst
.X(), rOfst
.Y()+nHLinSzHeight
);
866 aPos
.AdjustX(rSize
.Width() - nVLinSzWidth
);
867 nStyle
|= WB_RIGHT_ALIGNED
;
869 Size
aSize( nVLinSzWidth
, rEditSz
.Height() );
871 aSize
.setWidth( pVRuler
->GetSizePixel().Width() );
872 pVRuler
->SetStyle(nStyle
);
873 pVRuler
->SetPosSizePixel( aPos
, aSize
);
874 if(!pVRuler
->IsVisible())
877 // Ruler needs a resize, otherwise it will not work in the invisible condition
880 Size
aSize( rSize
.Width(), nHLinSzHeight
);
881 if ( nVBSzWidth
&& !bVRulerRight
)
882 aSize
.AdjustWidth( -nVBSzWidth
);
884 aSize
.setHeight( pHRuler
->GetSizePixel().Height() );
885 pHRuler
->SetPosSizePixel( rOfst
, aSize
);
886 // VCL calls no resize on invisible windows
887 // but that is not a good idea for the ruler
888 if(!pHRuler
->IsVisible())
892 // Arrange scrollbars and SizeBox
893 Point aScrollFillPos
;
895 Point
aPos( rOfst
.X(),
896 rOfst
.Y()+rSize
.Height()-nHBSzHeight
);
899 aPos
.AdjustX(nVBSzWidth
);
902 Size
aSize( rSize
.Width(), nHBSzHeight
);
904 aSize
.AdjustWidth( -nVBSzWidth
);
905 rHScrollbar
.SetPosSizePixel( aPos
, aSize
);
906 aScrollFillPos
.setY( aPos
.Y() );
909 Point
aPos( rOfst
.X()+rSize
.Width()-nVBSzWidth
,
911 Size
aSize( nVBSzWidth
, rSize
.Height() );
914 aPos
.setX( rOfst
.X() );
917 aPos
.AdjustY(nHLinSzHeight
);
918 aSize
.AdjustHeight( -nHLinSzHeight
);
923 aSize
.AdjustHeight( -nHBSzHeight
);
924 rVScrollbar
.SetPosSizePixel( aPos
, aSize
);
926 aPos
.AdjustY(aSize
.Height() );
928 aScrollFillPos
.setX( aPos
.X() );
932 void SwView::ShowAtResize()
934 m_bShowAtResize
= false;
935 if ( m_pWrtShell
->GetViewOptions()->IsViewHRuler() )
939 void SwView::InnerResizePixel( const Point
&rOfst
, const Size
&rSize
, bool )
941 Size aObjSize
= GetObjectShell()->GetVisArea().GetSize();
942 if ( !aObjSize
.IsEmpty() )
944 SvBorder
aBorder( GetBorderPixel() );
946 aSize
.AdjustWidth( -(aBorder
.Left() + aBorder
.Right()) );
947 aSize
.AdjustHeight( -(aBorder
.Top() + aBorder
.Bottom()) );
948 Size aObjSizePixel
= GetWindow()->LogicToPixel(aObjSize
, MapMode(MapUnit::MapTwip
));
949 SfxViewShell::SetZoomFactor( Fraction( aSize
.Width(), aObjSizePixel
.Width() ),
950 Fraction( aSize
.Height(), aObjSizePixel
.Height() ) );
953 m_bInInnerResizePixel
= true;
954 const bool bHScrollVisible
= m_pHScrollbar
->IsScrollbarVisible(true);
955 const bool bVScrollVisible
= m_pVScrollbar
->IsScrollbarVisible(true);
956 bool bRepeat
= false;
961 CalcAndSetBorderPixel( aBorder
);
962 if ( GetViewFrame().GetFrame().IsInPlace() )
964 Size
aViewSize( aSz
);
965 Point
aViewPos( rOfst
);
966 aViewSize
.AdjustHeight( -(aBorder
.Top() + aBorder
.Bottom()) );
967 aViewSize
.AdjustWidth( -(aBorder
.Left() + aBorder
.Right()) );
968 aViewPos
.AdjustX(aBorder
.Left() );
969 aViewPos
.AdjustY(aBorder
.Top() );
970 GetEditWin().SetPosSizePixel( aViewPos
, aViewSize
);
974 aSz
.AdjustHeight(aBorder
.Top() + aBorder
.Bottom() );
975 aSz
.AdjustWidth(aBorder
.Left() + aBorder
.Right() );
978 Size
aEditSz( GetEditWin().GetOutputSizePixel() );
979 ViewResizePixel( *GetEditWin().GetOutDev(), rOfst
, aSz
, aEditSz
, *m_pVScrollbar
,
980 *m_pHScrollbar
, m_pVRuler
, m_pHRuler
,
981 m_pWrtShell
->GetViewOptions()->IsVRulerRight());
982 if ( m_bShowAtResize
)
985 if( m_pHRuler
->IsVisible() || m_pVRuler
->IsVisible() )
987 const Fraction
& rFrac
= GetEditWin().GetMapMode().GetScaleX();
988 tools::Long nZoom
= 100;
990 nZoom
= tools::Long(rFrac
* 100);
992 const Fraction
aFrac( nZoom
, 100 );
993 m_pVRuler
->SetZoom( aFrac
);
994 m_pHRuler
->SetZoom( aFrac
);
995 InvalidateRulerPos(); // Invalidate content.
997 // Reset the cursor stack because the cursor positions for PageUp/Down
998 // no longer fit the currently visible area.
999 m_pWrtShell
->ResetCursorStack();
1001 // EditWin never set!
1003 // Set VisArea, but do not call the SetVisArea of the Docshell there!
1004 bProtectDocShellVisArea
= true;
1005 CalcVisArea( aEditSz
);
1006 // Visibility changes of the automatic horizontal scrollbar
1007 // require to repeat the ViewResizePixel() call - but only once!
1010 else if(bHScrollVisible
!= m_pHScrollbar
->IsScrollbarVisible(true) ||
1011 bVScrollVisible
!= m_pVScrollbar
->IsScrollbarVisible(true))
1014 bProtectDocShellVisArea
= false;
1015 m_bInInnerResizePixel
= false;
1018 void SwView::OuterResizePixel( const Point
&rOfst
, const Size
&rSize
)
1020 // #i16909# return, if no size (caused by minimize window).
1021 if ( m_bInOuterResizePixel
|| ( !rSize
.Width() && !rSize
.Height() ) )
1023 m_bInOuterResizePixel
= true;
1025 // Determine whether scroll bars may be displayed.
1031 const SwViewOption
*pVOpt
= m_pWrtShell
->GetViewOptions();
1032 if ( !pVOpt
->IsReadonly() || pVOpt
->IsStarOneSetting() )
1034 bShowH
= pVOpt
->IsViewHScrollBar();
1035 bShowV
= pVOpt
->IsViewVScrollBar();
1038 if (!m_bHScrollbarEnabled
)
1040 bHAuto
= bShowH
= false;
1042 if (!m_bVScrollbarEnabled
)
1044 bAuto
= bShowV
= false;
1047 SwDocShell
* pDocSh
= GetDocShell();
1048 bool bIsPreview
= pDocSh
->IsPreview();
1051 bShowH
= bShowV
= bHAuto
= bAuto
= false;
1053 if(m_pHScrollbar
->IsScrollbarVisible(false) != bShowH
&& !bHAuto
)
1054 ShowHScrollbar(bShowH
);
1055 m_pHScrollbar
->SetAuto( bHAuto
);
1056 if(m_pVScrollbar
->IsScrollbarVisible(false) != bShowV
&& !bAuto
)
1057 ShowVScrollbar(bShowV
);
1058 m_pVScrollbar
->SetAuto(bAuto
);
1060 CurrShell
aCurr( m_pWrtShell
.get() );
1061 bool bRepeat
= false;
1062 tools::Long nCnt
= 0;
1064 bool bUnLockView
= !m_pWrtShell
->IsViewLocked();
1065 m_pWrtShell
->LockView( true );
1066 m_pWrtShell
->LockPaint(LockPaintReason::OuterResize
);
1070 const bool bScroll1
= m_pVScrollbar
->IsScrollbarVisible(true);
1071 const bool bScroll2
= m_pHScrollbar
->IsScrollbarVisible(true);
1073 CalcAndSetBorderPixel( aBorder
);
1074 const Size
aEditSz( GetEditWin().GetOutputSizePixel() );
1075 ViewResizePixel( *GetEditWin().GetOutDev(), rOfst
, rSize
, aEditSz
, *m_pVScrollbar
,
1076 *m_pHScrollbar
, m_pVRuler
, m_pHRuler
,
1077 m_pWrtShell
->GetViewOptions()->IsVRulerRight() );
1078 if ( m_bShowAtResize
)
1081 if( m_pHRuler
->IsVisible() || m_pVRuler
->IsVisible() )
1082 InvalidateRulerPos(); // Invalidate content.
1084 // Reset the cursor stack because the cursor positions for PageUp/Down
1085 // no longer fit the currently visible area.
1086 m_pWrtShell
->ResetCursorStack();
1088 OSL_ENSURE( !GetEditWin().IsVisible() ||
1089 !aEditSz
.IsEmpty() || !m_aVisArea
.IsEmpty(), "Small world, isn't it?" );
1091 // Never set EditWin!
1093 // Of course the VisArea must also be set.
1094 // Now is the right time to re-calculate the zoom if it is not a simple factor.
1095 m_pWrtShell
->StartAction();
1096 CalcVisArea( aEditSz
);
1098 //Thus also in the outplace editing the page width will be adjusted immediately.
1099 //TODO/LATER: is that still necessary?!
1101 if ( pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
1103 pDocSh->SfxInPlaceObject::GetVisArea() );*/
1104 if ( m_pWrtShell
->GetViewOptions()->GetZoomType() != SvxZoomType::PERCENT
&&
1105 !m_pWrtShell
->GetViewOptions()->getBrowseMode() )
1106 SetZoom_( aEditSz
, m_pWrtShell
->GetViewOptions()->GetZoomType(), 100, true );
1107 m_pWrtShell
->EndAction();
1109 bRepeat
= bScroll1
!= m_pVScrollbar
->IsScrollbarVisible(true);
1111 bRepeat
= bScroll2
!= m_pHScrollbar
->IsScrollbarVisible(true);
1113 // Do no infinite loops.
1114 // If possible stop when the (auto-) scroll bars are visible.
1116 ( nCnt
> 10 || ( nCnt
> 3 && bHAuto
&& bAuto
) )
1122 } while ( bRepeat
);
1124 m_pWrtShell
->UnlockPaint();
1126 m_pWrtShell
->LockView( false );
1128 m_bInOuterResizePixel
= false;
1132 m_pPostItMgr
->CalcRects();
1133 m_pPostItMgr
->LayoutPostIts();
1137 void SwView::SetZoomFactor( const Fraction
&rX
, const Fraction
&rY
)
1139 const Fraction
&rFrac
= rX
< rY
? rX
: rY
;
1140 SetZoom( SvxZoomType::PERCENT
, static_cast<short>(tools::Long(rFrac
* Fraction( 100, 1 ))) );
1142 // To minimize rounding errors we also adjust the odd values
1143 // of the base class if necessary.
1144 SfxViewShell::SetZoomFactor( rX
, rY
);
1147 bool SwView::UpdateScrollbars()
1150 if ( !m_aVisArea
.IsEmpty() )
1152 const bool bBorder
= IsDocumentBorder();
1153 tools::Rectangle
aTmpRect( m_aVisArea
);
1156 Point
aPt( DOCUMENTBORDER
, DOCUMENTBORDER
);
1157 aPt
= AlignToPixel( aPt
);
1158 aTmpRect
.Move( -aPt
.X(), -aPt
.Y() );
1161 Size
aTmpSz( m_aDocSz
);
1162 const tools::Long lOfst
= bBorder
? 0 : DOCUMENTBORDER
* 2;
1163 aTmpSz
.AdjustWidth(lOfst
); aTmpSz
.AdjustHeight(lOfst
);
1166 const bool bVScrollVisible
= m_pVScrollbar
->IsScrollbarVisible(true);
1167 m_pVScrollbar
->DocSzChgd( aTmpSz
);
1168 m_pVScrollbar
->ViewPortChgd( aTmpRect
);
1169 if ( bVScrollVisible
!= m_pVScrollbar
->IsScrollbarVisible(true) )
1173 const bool bHScrollVisible
= m_pHScrollbar
->IsScrollbarVisible(true);
1174 m_pHScrollbar
->DocSzChgd( aTmpSz
);
1175 m_pHScrollbar
->ViewPortChgd( aTmpRect
);
1176 if ( bHScrollVisible
!= m_pHScrollbar
->IsScrollbarVisible(true) )
1185 if ( GetWrtShell().IsInSelect() )
1186 GetWrtShell().EndSelect();
1187 SfxViewShell::Move();
1190 bool SwView::HandleWheelCommands( const CommandEvent
& rCEvt
)
1193 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
1194 if (pWData
&& CommandWheelMode::ZOOM
== pWData
->GetMode())
1196 sal_uInt16 nFact
= m_pWrtShell
->GetViewOptions()->GetZoom();
1197 if( 0L > pWData
->GetDelta() )
1198 nFact
= std::max(MIN_ZOOM_PERCENT
, basegfx::zoomtools::zoomOut( nFact
));
1200 nFact
= std::min(MAX_ZOOM_PERCENT
, basegfx::zoomtools::zoomIn( nFact
));
1202 SetZoom( SvxZoomType::PERCENT
, nFact
);
1207 if (pWData
&& pWData
->GetMode()==CommandWheelMode::SCROLL
)
1209 // This influences whether quick help is shown
1210 m_bWheelScrollInProgress
=true;
1213 if (pWData
&& (CommandWheelMode::SCROLL
==pWData
->GetMode()) &&
1214 (COMMAND_WHEEL_PAGESCROLL
== pWData
->GetScrollLines()))
1216 if (pWData
->GetDelta()<0)
1223 bOk
= m_pEditWin
->HandleScrollCommand(rCEvt
, m_pHScrollbar
, m_pVScrollbar
);
1225 // Restore default state for case when scroll command comes from dragging scrollbar handle
1226 m_bWheelScrollInProgress
=false;
1231 bool SwView::HandleGestureZoomCommand(const CommandEvent
& rCEvt
)
1233 const CommandGestureZoomData
* pData
= rCEvt
.GetGestureZoomData();
1235 if (pData
->meEventType
== GestureEventZoomType::Begin
)
1237 m_fLastZoomScale
= pData
->mfScaleDelta
;
1241 if (pData
->meEventType
== GestureEventZoomType::Update
)
1243 double deltaBetweenEvents
= (pData
->mfScaleDelta
- m_fLastZoomScale
) / m_fLastZoomScale
;
1244 m_fLastZoomScale
= pData
->mfScaleDelta
;
1246 // Accumulate fractional zoom to avoid small zoom changes from being ignored
1247 m_fAccumulatedZoom
+= deltaBetweenEvents
;
1248 int nZoomChangePercent
= m_fAccumulatedZoom
* 100;
1249 m_fAccumulatedZoom
-= nZoomChangePercent
/ 100.0;
1251 sal_uInt16 nFact
= m_pWrtShell
->GetViewOptions()->GetZoom();
1252 nFact
+= nZoomChangePercent
;
1253 nFact
= std::clamp
<sal_uInt16
>(nFact
, MIN_ZOOM_PERCENT
, MAX_ZOOM_PERCENT
);
1254 SetZoom(SvxZoomType::PERCENT
, nFact
);
1261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */